summaryrefslogtreecommitdiff
path: root/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc')
-rw-r--r--src/lib/libc/crypt/Makefile.inc16
-rw-r--r--src/lib/libc/crypt/arc4random.3136
-rw-r--r--src/lib/libc/crypt/arc4random.c272
-rw-r--r--src/lib/libc/crypt/bcrypt.c338
-rw-r--r--src/lib/libc/crypt/blowfish.3106
-rw-r--r--src/lib/libc/crypt/blowfish.c685
-rw-r--r--src/lib/libc/crypt/cast.c790
-rw-r--r--src/lib/libc/crypt/crypt.3324
-rw-r--r--src/lib/libc/crypt/crypt.c696
-rw-r--r--src/lib/libc/crypt/crypt2.c104
-rw-r--r--src/lib/libc/crypt/md5crypt.c149
-rw-r--r--src/lib/libc/crypt/skipjack.c260
-rw-r--r--src/lib/libc/include/ctype_private.h7
-rw-r--r--src/lib/libc/include/namespace.h2
-rw-r--r--src/lib/libc/include/thread_private.h160
-rw-r--r--src/lib/libc/net/Makefile.inc97
-rw-r--r--src/lib/libc/net/base64.c308
-rw-r--r--src/lib/libc/net/byteorder.3186
-rw-r--r--src/lib/libc/net/ethers.380
-rw-r--r--src/lib/libc/net/ethers.c188
-rw-r--r--src/lib/libc/net/freeaddrinfo.c (renamed from src/lib/libc/stdlib/calloc.c)39
-rw-r--r--src/lib/libc/net/gai_strerror.393
-rw-r--r--src/lib/libc/net/gai_strerror.c (renamed from src/lib/libc/string/__strsignal.c)96
-rw-r--r--src/lib/libc/net/getaddrinfo.3437
-rw-r--r--src/lib/libc/net/getaddrinfo.c1748
-rw-r--r--src/lib/libc/net/gethostbyname.3239
-rw-r--r--src/lib/libc/net/gethostnamadr.c975
-rw-r--r--src/lib/libc/net/getifaddrs.3157
-rw-r--r--src/lib/libc/net/getifaddrs.c277
-rw-r--r--src/lib/libc/net/getnameinfo.3266
-rw-r--r--src/lib/libc/net/getnameinfo.c351
-rw-r--r--src/lib/libc/net/getnetbyaddr.c25
-rw-r--r--src/lib/libc/net/getnetbyname.c30
-rw-r--r--src/lib/libc/net/getnetent.383
-rw-r--r--src/lib/libc/net/getnetent.c52
-rw-r--r--src/lib/libc/net/getnetnamadr.c384
-rw-r--r--src/lib/libc/net/getproto.c50
-rw-r--r--src/lib/libc/net/getprotoent.3153
-rw-r--r--src/lib/libc/net/getprotoent.c145
-rw-r--r--src/lib/libc/net/getprotoname.c57
-rw-r--r--src/lib/libc/net/getrrsetbyname.3166
-rw-r--r--src/lib/libc/net/getrrsetbyname.c514
-rw-r--r--src/lib/libc/net/getservbyname.c59
-rw-r--r--src/lib/libc/net/getservbyport.c56
-rw-r--r--src/lib/libc/net/getservent.3163
-rw-r--r--src/lib/libc/net/getservent.c147
-rw-r--r--src/lib/libc/net/herror.c53
-rw-r--r--src/lib/libc/net/htonl.c20
-rw-r--r--src/lib/libc/net/htons.c14
-rw-r--r--src/lib/libc/net/if_indextoname.3144
-rw-r--r--src/lib/libc/net/if_indextoname.c86
-rw-r--r--src/lib/libc/net/if_nameindex.c140
-rw-r--r--src/lib/libc/net/if_nametoindex.c81
-rw-r--r--src/lib/libc/net/inet.3264
-rw-r--r--src/lib/libc/net/inet6_opt_init.3338
-rw-r--r--src/lib/libc/net/inet6_option_space.3444
-rw-r--r--src/lib/libc/net/inet6_rth_space.3219
-rw-r--r--src/lib/libc/net/inet6_rthdr_space.3314
-rw-r--r--src/lib/libc/net/inet_addr.c111
-rw-r--r--src/lib/libc/net/inet_lnaof.c24
-rw-r--r--src/lib/libc/net/inet_makeaddr.c22
-rw-r--r--src/lib/libc/net/inet_net.3176
-rw-r--r--src/lib/libc/net/inet_net_ntop.c135
-rw-r--r--src/lib/libc/net/inet_net_pton.c191
-rw-r--r--src/lib/libc/net/inet_neta.c80
-rw-r--r--src/lib/libc/net/inet_netof.c24
-rw-r--r--src/lib/libc/net/inet_network.c41
-rw-r--r--src/lib/libc/net/inet_ntoa.c24
-rw-r--r--src/lib/libc/net/inet_ntop.c195
-rw-r--r--src/lib/libc/net/inet_pton.c212
-rw-r--r--src/lib/libc/net/ip6opt.c596
-rw-r--r--src/lib/libc/net/iso_addr.3112
-rw-r--r--src/lib/libc/net/iso_addr.c125
-rw-r--r--src/lib/libc/net/link_addr.3 (renamed from src/lib/libc/net/linkaddr.3)40
-rw-r--r--src/lib/libc/net/linkaddr.c34
-rw-r--r--src/lib/libc/net/net_addrcmp.391
-rw-r--r--src/lib/libc/net/net_addrcmp.c63
-rw-r--r--src/lib/libc/net/ns.3132
-rw-r--r--src/lib/libc/net/ns_addr.c233
-rw-r--r--src/lib/libc/net/ns_ntoa.c106
-rw-r--r--src/lib/libc/net/nsap_addr.c94
-rw-r--r--src/lib/libc/net/ntohl.c20
-rw-r--r--src/lib/libc/net/ntohs.c14
-rw-r--r--src/lib/libc/net/rcmd.3174
-rw-r--r--src/lib/libc/net/rcmd.c558
-rw-r--r--src/lib/libc/net/rcmdsh.396
-rw-r--r--src/lib/libc/net/rcmdsh.c186
-rw-r--r--src/lib/libc/net/recv.c22
-rw-r--r--src/lib/libc/net/res_comp.c269
-rw-r--r--src/lib/libc/net/res_data.c105
-rw-r--r--src/lib/libc/net/res_debug.c1432
-rw-r--r--src/lib/libc/net/res_debug_syms.c189
-rw-r--r--src/lib/libc/net/res_init.c554
-rw-r--r--src/lib/libc/net/res_mkquery.c258
-rw-r--r--src/lib/libc/net/res_query.c262
-rw-r--r--src/lib/libc/net/res_random.c264
-rw-r--r--src/lib/libc/net/res_send.c863
-rw-r--r--src/lib/libc/net/resolver.3172
-rw-r--r--src/lib/libc/net/rresvport.c107
-rw-r--r--src/lib/libc/net/rthdr.c378
-rw-r--r--src/lib/libc/net/send.c22
-rw-r--r--src/lib/libc/net/sethostent.c35
-rw-r--r--src/lib/libc/net/vars6.c42
-rw-r--r--src/lib/libc/stdlib/Makefile.inc64
-rw-r--r--src/lib/libc/stdlib/_Exit.c22
-rw-r--r--src/lib/libc/stdlib/_rand48.c1
-rw-r--r--src/lib/libc/stdlib/a64l.3133
-rw-r--r--src/lib/libc/stdlib/a64l.c30
-rw-r--r--src/lib/libc/stdlib/abort.328
-rw-r--r--src/lib/libc/stdlib/abort.c41
-rw-r--r--src/lib/libc/stdlib/abs.326
-rw-r--r--src/lib/libc/stdlib/abs.c15
-rw-r--r--src/lib/libc/stdlib/alloca.343
-rw-r--r--src/lib/libc/stdlib/atexit.327
-rw-r--r--src/lib/libc/stdlib/atexit.c233
-rw-r--r--src/lib/libc/stdlib/atexit.h67
-rw-r--r--src/lib/libc/stdlib/atof.315
-rw-r--r--src/lib/libc/stdlib/atof.c15
-rw-r--r--src/lib/libc/stdlib/atoi.337
-rw-r--r--src/lib/libc/stdlib/atoi.c15
-rw-r--r--src/lib/libc/stdlib/atol.321
-rw-r--r--src/lib/libc/stdlib/atol.c15
-rw-r--r--src/lib/libc/stdlib/atoll.3 (renamed from src/lib/libc/stdlib/calloc.3)61
-rw-r--r--src/lib/libc/stdlib/atoll.c (renamed from src/lib/libc/string/__strerror.c)68
-rw-r--r--src/lib/libc/stdlib/bsearch.325
-rw-r--r--src/lib/libc/stdlib/bsearch.c25
-rw-r--r--src/lib/libc/stdlib/cfree.c40
-rw-r--r--src/lib/libc/stdlib/div.327
-rw-r--r--src/lib/libc/stdlib/div.c15
-rw-r--r--src/lib/libc/stdlib/drand48.c1
-rw-r--r--src/lib/libc/stdlib/ecvt.3165
-rw-r--r--src/lib/libc/stdlib/ecvt.c105
-rw-r--r--src/lib/libc/stdlib/erand48.c1
-rw-r--r--src/lib/libc/stdlib/exit.366
-rw-r--r--src/lib/libc/stdlib/exit.c40
-rw-r--r--src/lib/libc/stdlib/free.382
-rw-r--r--src/lib/libc/stdlib/gcvt.c111
-rw-r--r--src/lib/libc/stdlib/getenv.380
-rw-r--r--src/lib/libc/stdlib/getenv.c74
-rw-r--r--src/lib/libc/stdlib/getopt.3315
-rw-r--r--src/lib/libc/stdlib/getopt.c118
-rw-r--r--src/lib/libc/stdlib/getopt_long.3464
-rw-r--r--src/lib/libc/stdlib/getopt_long.c517
-rw-r--r--src/lib/libc/stdlib/getsubopt.3145
-rw-r--r--src/lib/libc/stdlib/getsubopt.c92
-rw-r--r--src/lib/libc/stdlib/hcreate.3184
-rw-r--r--src/lib/libc/stdlib/hcreate.c191
-rw-r--r--src/lib/libc/stdlib/heapsort.c27
-rw-r--r--src/lib/libc/stdlib/imaxabs.3 (renamed from src/lib/libc/string/index.3)79
-rw-r--r--src/lib/libc/stdlib/imaxabs.c38
-rw-r--r--src/lib/libc/stdlib/imaxdiv.3 (renamed from src/lib/libc/string/rindex.3)80
-rw-r--r--src/lib/libc/stdlib/imaxdiv.c50
-rw-r--r--src/lib/libc/stdlib/insque.3106
-rw-r--r--src/lib/libc/stdlib/insque.c48
-rw-r--r--src/lib/libc/stdlib/jrand48.c1
-rw-r--r--src/lib/libc/stdlib/l64a.c17
-rw-r--r--src/lib/libc/stdlib/labs.336
-rw-r--r--src/lib/libc/stdlib/labs.c15
-rw-r--r--src/lib/libc/stdlib/lcong48.c1
-rw-r--r--src/lib/libc/stdlib/ldiv.333
-rw-r--r--src/lib/libc/stdlib/ldiv.c15
-rw-r--r--src/lib/libc/stdlib/llabs.c38
-rw-r--r--src/lib/libc/stdlib/lldiv.3 (renamed from src/lib/libc/stdlib/memory.3)74
-rw-r--r--src/lib/libc/stdlib/lldiv.c50
-rw-r--r--src/lib/libc/stdlib/lrand48.c1
-rw-r--r--src/lib/libc/stdlib/lsearch.3108
-rw-r--r--src/lib/libc/stdlib/lsearch.c88
-rw-r--r--src/lib/libc/stdlib/malloc.3425
-rw-r--r--src/lib/libc/stdlib/malloc.c1673
-rw-r--r--src/lib/libc/stdlib/merge.c43
-rw-r--r--src/lib/libc/stdlib/mrand48.c1
-rw-r--r--src/lib/libc/stdlib/multibyte.c131
-rw-r--r--src/lib/libc/stdlib/nrand48.c1
-rw-r--r--src/lib/libc/stdlib/putenv.c31
-rw-r--r--src/lib/libc/stdlib/qabs.321
-rw-r--r--src/lib/libc/stdlib/qabs.c15
-rw-r--r--src/lib/libc/stdlib/qdiv.326
-rw-r--r--src/lib/libc/stdlib/qdiv.c15
-rw-r--r--src/lib/libc/stdlib/qsort.393
-rw-r--r--src/lib/libc/stdlib/qsort.c58
-rw-r--r--src/lib/libc/stdlib/radixsort.356
-rw-r--r--src/lib/libc/stdlib/radixsort.c66
-rw-r--r--src/lib/libc/stdlib/rand.337
-rw-r--r--src/lib/libc/stdlib/rand.c27
-rw-r--r--src/lib/libc/stdlib/rand48.347
-rw-r--r--src/lib/libc/stdlib/rand48.h4
-rw-r--r--src/lib/libc/stdlib/random.3114
-rw-r--r--src/lib/libc/stdlib/random.c131
-rw-r--r--src/lib/libc/stdlib/realloc.3100
-rw-r--r--src/lib/libc/stdlib/realpath.361
-rw-r--r--src/lib/libc/stdlib/realpath.c237
-rw-r--r--src/lib/libc/stdlib/remque.c44
-rw-r--r--src/lib/libc/stdlib/seed48.c1
-rw-r--r--src/lib/libc/stdlib/setenv.c75
-rw-r--r--src/lib/libc/stdlib/srand48.c1
-rw-r--r--src/lib/libc/stdlib/strtod.367
-rw-r--r--src/lib/libc/stdlib/strtod.c522
-rw-r--r--src/lib/libc/stdlib/strtof.c39
-rw-r--r--src/lib/libc/stdlib/strtoimax.c140
-rw-r--r--src/lib/libc/stdlib/strtol.3195
-rw-r--r--src/lib/libc/stdlib/strtol.c86
-rw-r--r--src/lib/libc/stdlib/strtoll.c (renamed from src/lib/libc/stdlib/strtoq.c)97
-rw-r--r--src/lib/libc/stdlib/strtonum.3152
-rw-r--r--src/lib/libc/stdlib/strtonum.c65
-rw-r--r--src/lib/libc/stdlib/strtoul.3176
-rw-r--r--src/lib/libc/stdlib/strtoul.c60
-rw-r--r--src/lib/libc/stdlib/strtoull.c (renamed from src/lib/libc/stdlib/strtouq.c)69
-rw-r--r--src/lib/libc/stdlib/strtoumax.c102
-rw-r--r--src/lib/libc/stdlib/system.357
-rw-r--r--src/lib/libc/stdlib/system.c35
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3127
-rw-r--r--src/lib/libc/stdlib/tsearch.c121
-rw-r--r--src/lib/libc/string/Makefile.inc126
-rw-r--r--src/lib/libc/string/bcmp.318
-rw-r--r--src/lib/libc/string/bcmp.c30
-rw-r--r--src/lib/libc/string/bcopy.327
-rw-r--r--src/lib/libc/string/bcopy.c27
-rw-r--r--src/lib/libc/string/bm.3116
-rw-r--r--src/lib/libc/string/bm.c39
-rw-r--r--src/lib/libc/string/bstring.338
-rw-r--r--src/lib/libc/string/bzero.319
-rw-r--r--src/lib/libc/string/bzero.c23
-rw-r--r--src/lib/libc/string/ffs.317
-rw-r--r--src/lib/libc/string/ffs.c77
-rw-r--r--src/lib/libc/string/index.c17
-rw-r--r--src/lib/libc/string/memccpy.334
-rw-r--r--src/lib/libc/string/memccpy.c29
-rw-r--r--src/lib/libc/string/memchr.347
-rw-r--r--src/lib/libc/string/memchr.c21
-rw-r--r--src/lib/libc/string/memcmp.324
-rw-r--r--src/lib/libc/string/memcmp.c18
-rw-r--r--src/lib/libc/string/memcpy.333
-rw-r--r--src/lib/libc/string/memmove.328
-rw-r--r--src/lib/libc/string/memrchr.c38
-rw-r--r--src/lib/libc/string/memset.326
-rw-r--r--src/lib/libc/string/memset.c22
-rw-r--r--src/lib/libc/string/rindex.c19
-rw-r--r--src/lib/libc/string/strcasecmp.330
-rw-r--r--src/lib/libc/string/strcasecmp.c36
-rw-r--r--src/lib/libc/string/strcasestr.c60
-rw-r--r--src/lib/libc/string/strcat.379
-rw-r--r--src/lib/libc/string/strcat.c28
-rw-r--r--src/lib/libc/string/strchr.360
-rw-r--r--src/lib/libc/string/strcmp.325
-rw-r--r--src/lib/libc/string/strcmp.c20
-rw-r--r--src/lib/libc/string/strcoll.319
-rw-r--r--src/lib/libc/string/strcoll.c15
-rw-r--r--src/lib/libc/string/strcpy.383
-rw-r--r--src/lib/libc/string/strcpy.c28
-rw-r--r--src/lib/libc/string/strcspn.351
-rw-r--r--src/lib/libc/string/strcspn.c20
-rw-r--r--src/lib/libc/string/strdup.361
-rw-r--r--src/lib/libc/string/strdup.c31
-rw-r--r--src/lib/libc/string/strerror.373
-rw-r--r--src/lib/libc/string/strerror.c27
-rw-r--r--src/lib/libc/string/strerror_r.c137
-rw-r--r--src/lib/libc/string/strftime.3202
-rw-r--r--src/lib/libc/string/strftime.c317
-rw-r--r--src/lib/libc/string/string.364
-rw-r--r--src/lib/libc/string/strlcat.c55
-rw-r--r--src/lib/libc/string/strlcpy.3186
-rw-r--r--src/lib/libc/string/strlcpy.c51
-rw-r--r--src/lib/libc/string/strlen.326
-rw-r--r--src/lib/libc/string/strlen.c31
-rw-r--r--src/lib/libc/string/strmode.378
-rw-r--r--src/lib/libc/string/strmode.c18
-rw-r--r--src/lib/libc/string/strncat.c21
-rw-r--r--src/lib/libc/string/strncmp.c21
-rw-r--r--src/lib/libc/string/strncpy.c26
-rw-r--r--src/lib/libc/string/strpbrk.324
-rw-r--r--src/lib/libc/string/strpbrk.c19
-rw-r--r--src/lib/libc/string/strrchr.361
-rw-r--r--src/lib/libc/string/strsep.390
-rw-r--r--src/lib/libc/string/strsep.c32
-rw-r--r--src/lib/libc/string/strsignal.313
-rw-r--r--src/lib/libc/string/strsignal.c17
-rw-r--r--src/lib/libc/string/strspn.338
-rw-r--r--src/lib/libc/string/strspn.c20
-rw-r--r--src/lib/libc/string/strstr.355
-rw-r--r--src/lib/libc/string/strstr.c19
-rw-r--r--src/lib/libc/string/strtok.392
-rw-r--r--src/lib/libc/string/strtok.c34
-rw-r--r--src/lib/libc/string/strxfrm.339
-rw-r--r--src/lib/libc/string/strxfrm.c35
-rw-r--r--src/lib/libc/string/swab.315
-rw-r--r--src/lib/libc/string/swab.c37
-rw-r--r--src/lib/libc/string/wcscat.c55
-rw-r--r--src/lib/libc/string/wcschr.c50
-rw-r--r--src/lib/libc/string/wcscmp.c51
-rw-r--r--src/lib/libc/string/wcscpy.c52
-rw-r--r--src/lib/libc/string/wcscspn.c53
-rw-r--r--src/lib/libc/string/wcslcat.c68
-rw-r--r--src/lib/libc/string/wcslcpy.c64
-rw-r--r--src/lib/libc/string/wcslen.c44
-rw-r--r--src/lib/libc/string/wcsncat.c52
-rw-r--r--src/lib/libc/string/wcsncmp.c52
-rw-r--r--src/lib/libc/string/wcsncpy.c50
-rw-r--r--src/lib/libc/string/wcspbrk.c53
-rw-r--r--src/lib/libc/string/wcsrchr.c50
-rw-r--r--src/lib/libc/string/wcsspn.c55
-rw-r--r--src/lib/libc/string/wcsstr.c70
-rw-r--r--src/lib/libc/string/wcstok.3136
-rw-r--r--src/lib/libc/string/wcstok.c93
-rw-r--r--src/lib/libc/string/wcswcs.c5
-rw-r--r--src/lib/libc/string/wcswidth.c47
-rw-r--r--src/lib/libc/string/wmemchr.3141
-rw-r--r--src/lib/libc/string/wmemchr.c47
-rw-r--r--src/lib/libc/string/wmemcmp.c50
-rw-r--r--src/lib/libc/string/wmemcpy.c40
-rw-r--r--src/lib/libc/string/wmemmove.c40
-rw-r--r--src/lib/libc/string/wmemset.c46
312 files changed, 29923 insertions, 8189 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc
new file mode 100644
index 0000000000..d961f36b52
--- /dev/null
+++ b/src/lib/libc/crypt/Makefile.inc
@@ -0,0 +1,16 @@
1# $OpenBSD: Makefile.inc,v 1.16 2008/03/16 22:08:12 deraadt Exp $
2
3.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/crypt ${LIBCSRCDIR}/crypt
4
5SRCS+= cast.c crypt.c crypt2.c md5crypt.c arc4random.c blowfish.c
6SRCS+= bcrypt.c skipjack.c
7
8MAN+= crypt.3 blowfish.3 arc4random.3
9MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_cipher.3
10MLINKS+=crypt.3 bcrypt_gensalt.3 crypt.3 bcrypt.3 crypt.3 md5crypt.3
11MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3
12MLINKS+=blowfish.3 blf_dec.3 blowfish.3 blf_ecb_encrypt.3
13MLINKS+=blowfish.3 blf_ecb_decrypt.3 blowfish.3 blf_cbc_encrypt.3
14MLINKS+=blowfish.3 blf_cbc_decrypt.3
15MLINKS+=arc4random.3 arc4random_stir.3 arc4random.3 arc4random_addrandom.3
16MLINKS+=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..2a12c6d94e
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.3
@@ -0,0 +1,136 @@
1.\" $OpenBSD: arc4random.3,v 1.26 2008/06/09 06:04:02 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: June 9 2008 $
34.Dt ARC4RANDOM 3
35.Os
36.Sh NAME
37.Nm arc4random ,
38.Nm arc4random_buf ,
39.Nm arc4random_uniform ,
40.Nm arc4random_stir ,
41.Nm arc4random_addrandom
42.Nd arc4 random number generator
43.Sh SYNOPSIS
44.Fd #include <stdlib.h>
45.Ft u_int32_t
46.Fn arc4random "void"
47.Ft void
48.Fn arc4random_buf "void *buf" "size_t nbytes"
49.Ft u_int32_t
50.Fn arc4random_uniform "u_int32_t upper_bound"
51.Ft void
52.Fn arc4random_stir "void"
53.Ft void
54.Fn arc4random_addrandom "u_char *dat" "int datlen"
55.Sh DESCRIPTION
56The
57.Fn arc4random
58function provides a high quality 32-bit pseudo-random
59number very quickly.
60.Fn arc4random
61seeds itself on a regular basis from the kernel strong random number
62subsystem described in
63.Xr random 4 .
64On each call, an ARC4 generator is used to generate a new result.
65The
66.Fn arc4random
67function uses the ARC4 cipher key stream generator,
68which uses 8*8 8-bit S-Boxes.
69The S-Boxes can be in about (2**1700) states.
70.Pp
71.Fn arc4random
72fits into a middle ground not covered by other subsystems such as
73the strong, slow, and resource expensive random
74devices described in
75.Xr random 4
76versus the fast but poor quality interfaces described in
77.Xr rand 3 ,
78.Xr random 3 ,
79and
80.Xr drand48 3 .
81.Pp
82.Fn arc4random_buf
83fills the region
84.Fa buf
85of length
86.Fa nbytes
87with ARC4-derived random data.
88.Pp
89.Fn arc4random_uniform
90will return a uniformly distributed random number less than
91.Fa upper_bound .
92.Fn arc4random_uniform
93is recommended over constructions like
94.Dq Li arc4random() % upper_bound
95as it avoids "modulo bias" when the upper bound is not a power of two.
96.Pp
97The
98.Fn arc4random_stir
99function reads data using
100.Xr sysctl 3
101from
102.Va kern.arandom
103and uses it to permute the S-Boxes via
104.Fn arc4random_addrandom .
105.Pp
106There is no need to call
107.Fn arc4random_stir
108before using
109.Fn arc4random ,
110since
111.Fn arc4random
112automatically initializes itself.
113.Sh RETURN VALUES
114These functions are always successful, and no return value is
115reserved to indicate an error.
116.Sh SEE ALSO
117.Xr rand 3 ,
118.Xr rand48 3 ,
119.Xr random 3
120.Sh HISTORY
121An algorithm called
122.Pa RC4
123was designed by RSA Data Security, Inc.
124It was considered a trade secret.
125Because it was a trade secret, it obviously could not be patented.
126A clone of this was posted anonymously to USENET and confirmed to
127be equivalent by several sources who had access to the original cipher.
128Because of the trade secret situation, RSA Data Security, Inc. can do
129nothing about the release of the ARC4 algorithm.
130Since
131.Pa RC4
132used to be a trade secret, the cipher is now referred to as
133.Pa ARC4 .
134.Pp
135These functions first appeared in
136.Ox 2.1 .
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
new file mode 100644
index 0000000000..22b8d1f3c1
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.c
@@ -0,0 +1,272 @@
1/* $OpenBSD: arc4random.c,v 1.19 2008/06/04 00:50:23 djm Exp $ */
2
3/*
4 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
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/*
21 * Arc4 random number generator for OpenBSD.
22 *
23 * This code is derived from section 17.1 of Applied Cryptography,
24 * second edition, which describes a stream cipher allegedly
25 * compatible with RSA Labs "RC4" cipher (the actual description of
26 * which is a trade secret). The same algorithm is used as a stream
27 * cipher called "arcfour" in Tatu Ylonen's ssh package.
28 *
29 * Here the stream cipher has been modified always to include the time
30 * when initializing the state. That makes it impossible to
31 * regenerate the same random sequence twice, so this can't be used
32 * for encryption, but will generate good random numbers.
33 *
34 * RC4 is a registered trademark of RSA Laboratories.
35 */
36
37#include <fcntl.h>
38#include <limits.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include <sys/types.h>
42#include <sys/param.h>
43#include <sys/time.h>
44#include <sys/sysctl.h>
45#include "thread_private.h"
46
47#ifdef __GNUC__
48#define inline __inline
49#else /* !__GNUC__ */
50#define inline
51#endif /* !__GNUC__ */
52
53struct arc4_stream {
54 u_int8_t i;
55 u_int8_t j;
56 u_int8_t s[256];
57};
58
59static int rs_initialized;
60static struct arc4_stream rs;
61static pid_t arc4_stir_pid;
62static int arc4_count;
63
64static inline u_int8_t arc4_getbyte(void);
65
66static inline void
67arc4_init(void)
68{
69 int n;
70
71 for (n = 0; n < 256; n++)
72 rs.s[n] = n;
73 rs.i = 0;
74 rs.j = 0;
75}
76
77static inline void
78arc4_addrandom(u_char *dat, int datlen)
79{
80 int n;
81 u_int8_t si;
82
83 rs.i--;
84 for (n = 0; n < 256; n++) {
85 rs.i = (rs.i + 1);
86 si = rs.s[rs.i];
87 rs.j = (rs.j + si + dat[n % datlen]);
88 rs.s[rs.i] = rs.s[rs.j];
89 rs.s[rs.j] = si;
90 }
91 rs.j = rs.i;
92}
93
94static void
95arc4_stir(void)
96{
97 int i, mib[2];
98 size_t len;
99 u_char rnd[128];
100
101 if (!rs_initialized) {
102 arc4_init();
103 rs_initialized = 1;
104 }
105
106 mib[0] = CTL_KERN;
107 mib[1] = KERN_ARND;
108
109 len = sizeof(rnd);
110 sysctl(mib, 2, rnd, &len, NULL, 0);
111
112 arc4_stir_pid = getpid();
113 arc4_addrandom(rnd, sizeof(rnd));
114
115 /*
116 * Discard early keystream, as per recommendations in:
117 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
118 */
119 for (i = 0; i < 256; i++)
120 (void)arc4_getbyte();
121 arc4_count = 1600000;
122}
123
124static inline u_int8_t
125arc4_getbyte(void)
126{
127 u_int8_t si, sj;
128
129 rs.i = (rs.i + 1);
130 si = rs.s[rs.i];
131 rs.j = (rs.j + si);
132 sj = rs.s[rs.j];
133 rs.s[rs.i] = sj;
134 rs.s[rs.j] = si;
135 return (rs.s[(si + sj) & 0xff]);
136}
137
138u_int8_t
139__arc4_getbyte(void)
140{
141 u_int8_t val;
142
143 _ARC4_LOCK();
144 if (--arc4_count == 0 || !rs_initialized)
145 arc4_stir();
146 val = arc4_getbyte();
147 _ARC4_UNLOCK();
148 return val;
149}
150
151static inline u_int32_t
152arc4_getword(void)
153{
154 u_int32_t val;
155 val = arc4_getbyte() << 24;
156 val |= arc4_getbyte() << 16;
157 val |= arc4_getbyte() << 8;
158 val |= arc4_getbyte();
159 return val;
160}
161
162void
163arc4random_stir(void)
164{
165 _ARC4_LOCK();
166 arc4_stir();
167 _ARC4_UNLOCK();
168}
169
170void
171arc4random_addrandom(u_char *dat, int datlen)
172{
173 _ARC4_LOCK();
174 if (!rs_initialized)
175 arc4_stir();
176 arc4_addrandom(dat, datlen);
177 _ARC4_UNLOCK();
178}
179
180u_int32_t
181arc4random(void)
182{
183 u_int32_t val;
184 _ARC4_LOCK();
185 arc4_count -= 4;
186 if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != getpid())
187 arc4_stir();
188 val = arc4_getword();
189 _ARC4_UNLOCK();
190 return val;
191}
192
193void
194arc4random_buf(void *_buf, size_t n)
195{
196 u_char *buf = (u_char *)_buf;
197 _ARC4_LOCK();
198 if (!rs_initialized || arc4_stir_pid != getpid())
199 arc4_stir();
200 while (n--) {
201 if (--arc4_count <= 0)
202 arc4_stir();
203 buf[n] = arc4_getbyte();
204 }
205 _ARC4_UNLOCK();
206}
207
208/*
209 * Calculate a uniformly distributed random number less than upper_bound
210 * avoiding "modulo bias".
211 *
212 * Uniformity is achieved by generating new random numbers until the one
213 * returned is outside the range [0, 2**32 % upper_bound). This
214 * guarantees the selected random number will be inside
215 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
216 * after reduction modulo upper_bound.
217 */
218u_int32_t
219arc4random_uniform(u_int32_t upper_bound)
220{
221 u_int32_t r, min;
222
223 if (upper_bound < 2)
224 return 0;
225
226#if (ULONG_MAX > 0xffffffffUL)
227 min = 0x100000000UL % upper_bound;
228#else
229 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
230 if (upper_bound > 0x80000000)
231 min = 1 + ~upper_bound; /* 2**32 - upper_bound */
232 else {
233 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
234 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
235 }
236#endif
237
238 /*
239 * This could theoretically loop forever but each retry has
240 * p > 0.5 (worst case, usually far better) of selecting a
241 * number inside the range we need, so it should rarely need
242 * to re-roll.
243 */
244 for (;;) {
245 r = arc4random();
246 if (r >= min)
247 break;
248 }
249
250 return r % upper_bound;
251}
252
253#if 0
254/*-------- Test code for i386 --------*/
255#include <stdio.h>
256#include <machine/pctr.h>
257int
258main(int argc, char **argv)
259{
260 const int iter = 1000000;
261 int i;
262 pctrval v;
263
264 v = rdtsc();
265 for (i = 0; i < iter; i++)
266 arc4random();
267 v = rdtsc() - v;
268 v /= iter;
269
270 printf("%qd cycles\n", v);
271}
272#endif
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
new file mode 100644
index 0000000000..207e76ea46
--- /dev/null
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -0,0 +1,338 @@
1/* $OpenBSD: bcrypt.c,v 1.24 2008/04/02 19:54:05 millert Exp $ */
2
3/*
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Niels Provos.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/* This password hashing algorithm was designed by David Mazieres
34 * <dm@lcs.mit.edu> and works as follows:
35 *
36 * 1. state := InitState ()
37 * 2. state := ExpandKey (state, salt, password) 3.
38 * REPEAT rounds:
39 * state := ExpandKey (state, 0, salt)
40 * state := ExpandKey(state, 0, password)
41 * 4. ctext := "OrpheanBeholderScryDoubt"
42 * 5. REPEAT 64:
43 * ctext := Encrypt_ECB (state, ctext);
44 * 6. RETURN Concatenate (salt, ctext);
45 *
46 */
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <sys/types.h>
51#include <string.h>
52#include <pwd.h>
53#include <blf.h>
54
55/* This implementation is adaptable to current computing power.
56 * You can have up to 2^31 rounds which should be enough for some
57 * time to come.
58 */
59
60#define BCRYPT_VERSION '2'
61#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
62#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
63#define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
64
65char *bcrypt_gensalt(u_int8_t);
66
67static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
68static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
69static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
70
71static char encrypted[_PASSWORD_LEN];
72static char gsalt[7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1];
73static char error[] = ":";
74
75const static u_int8_t Base64Code[] =
76"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
77
78const static u_int8_t index_64[128] = {
79 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
80 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
81 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
82 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
83 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
84 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
85 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
86 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
87 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
88 255, 255, 255, 255, 255, 255, 28, 29, 30,
89 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
90 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
91 51, 52, 53, 255, 255, 255, 255, 255
92};
93#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
94
95static void
96decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data)
97{
98 u_int8_t *bp = buffer;
99 u_int8_t *p = data;
100 u_int8_t c1, c2, c3, c4;
101 while (bp < buffer + len) {
102 c1 = CHAR64(*p);
103 c2 = CHAR64(*(p + 1));
104
105 /* Invalid data */
106 if (c1 == 255 || c2 == 255)
107 break;
108
109 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
110 if (bp >= buffer + len)
111 break;
112
113 c3 = CHAR64(*(p + 2));
114 if (c3 == 255)
115 break;
116
117 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
118 if (bp >= buffer + len)
119 break;
120
121 c4 = CHAR64(*(p + 3));
122 if (c4 == 255)
123 break;
124 *bp++ = ((c3 & 0x03) << 6) | c4;
125
126 p += 4;
127 }
128}
129
130static void
131encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
132{
133 salt[0] = '$';
134 salt[1] = BCRYPT_VERSION;
135 salt[2] = 'a';
136 salt[3] = '$';
137
138 snprintf(salt + 4, 4, "%2.2u$", logr);
139
140 encode_base64((u_int8_t *) salt + 7, csalt, clen);
141}
142/* Generates a salt for this version of crypt.
143 Since versions may change. Keeping this here
144 seems sensible.
145 */
146
147char *
148bcrypt_gensalt(u_int8_t log_rounds)
149{
150 u_int8_t csalt[BCRYPT_MAXSALT];
151 u_int16_t i;
152 u_int32_t seed = 0;
153
154 for (i = 0; i < BCRYPT_MAXSALT; i++) {
155 if (i % 4 == 0)
156 seed = arc4random();
157 csalt[i] = seed & 0xff;
158 seed = seed >> 8;
159 }
160
161 if (log_rounds < 4)
162 log_rounds = 4;
163 else if (log_rounds > 31)
164 log_rounds = 31;
165
166 encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
167 return gsalt;
168}
169/* We handle $Vers$log2(NumRounds)$salt+passwd$
170 i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
171
172char *
173bcrypt(const char *key, const char *salt)
174{
175 blf_ctx state;
176 u_int32_t rounds, i, k;
177 u_int16_t j;
178 u_int8_t key_len, salt_len, logr, minor;
179 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
180 u_int8_t csalt[BCRYPT_MAXSALT];
181 u_int32_t cdata[BCRYPT_BLOCKS];
182 int n;
183
184 /* Discard "$" identifier */
185 salt++;
186
187 if (*salt > BCRYPT_VERSION) {
188 /* How do I handle errors ? Return ':' */
189 return error;
190 }
191
192 /* Check for minor versions */
193 if (salt[1] != '$') {
194 switch (salt[1]) {
195 case 'a':
196 /* 'ab' should not yield the same as 'abab' */
197 minor = salt[1];
198 salt++;
199 break;
200 default:
201 return error;
202 }
203 } else
204 minor = 0;
205
206 /* Discard version + "$" identifier */
207 salt += 2;
208
209 if (salt[2] != '$')
210 /* Out of sync with passwd entry */
211 return error;
212
213 /* Computer power doesn't increase linear, 2^x should be fine */
214 n = atoi(salt);
215 if (n > 31 || n < 0)
216 return error;
217 logr = (u_int8_t)n;
218 if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS)
219 return error;
220
221 /* Discard num rounds + "$" identifier */
222 salt += 3;
223
224 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
225 return error;
226
227 /* We dont want the base64 salt but the raw data */
228 decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
229 salt_len = BCRYPT_MAXSALT;
230 key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
231
232 /* Setting up S-Boxes and Subkeys */
233 Blowfish_initstate(&state);
234 Blowfish_expandstate(&state, csalt, salt_len,
235 (u_int8_t *) key, key_len);
236 for (k = 0; k < rounds; k++) {
237 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
238 Blowfish_expand0state(&state, csalt, salt_len);
239 }
240
241 /* This can be precomputed later */
242 j = 0;
243 for (i = 0; i < BCRYPT_BLOCKS; i++)
244 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
245
246 /* Now do the encryption */
247 for (k = 0; k < 64; k++)
248 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
249
250 for (i = 0; i < BCRYPT_BLOCKS; i++) {
251 ciphertext[4 * i + 3] = cdata[i] & 0xff;
252 cdata[i] = cdata[i] >> 8;
253 ciphertext[4 * i + 2] = cdata[i] & 0xff;
254 cdata[i] = cdata[i] >> 8;
255 ciphertext[4 * i + 1] = cdata[i] & 0xff;
256 cdata[i] = cdata[i] >> 8;
257 ciphertext[4 * i + 0] = cdata[i] & 0xff;
258 }
259
260
261 i = 0;
262 encrypted[i++] = '$';
263 encrypted[i++] = BCRYPT_VERSION;
264 if (minor)
265 encrypted[i++] = minor;
266 encrypted[i++] = '$';
267
268 snprintf(encrypted + i, 4, "%2.2u$", logr);
269
270 encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
271 encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
272 4 * BCRYPT_BLOCKS - 1);
273 memset(&state, 0, sizeof(state));
274 memset(ciphertext, 0, sizeof(ciphertext));
275 memset(csalt, 0, sizeof(csalt));
276 memset(cdata, 0, sizeof(cdata));
277 return encrypted;
278}
279
280static void
281encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
282{
283 u_int8_t *bp = buffer;
284 u_int8_t *p = data;
285 u_int8_t c1, c2;
286 while (p < data + len) {
287 c1 = *p++;
288 *bp++ = Base64Code[(c1 >> 2)];
289 c1 = (c1 & 0x03) << 4;
290 if (p >= data + len) {
291 *bp++ = Base64Code[c1];
292 break;
293 }
294 c2 = *p++;
295 c1 |= (c2 >> 4) & 0x0f;
296 *bp++ = Base64Code[c1];
297 c1 = (c2 & 0x0f) << 2;
298 if (p >= data + len) {
299 *bp++ = Base64Code[c1];
300 break;
301 }
302 c2 = *p++;
303 c1 |= (c2 >> 6) & 0x03;
304 *bp++ = Base64Code[c1];
305 *bp++ = Base64Code[c2 & 0x3f];
306 }
307 *bp = '\0';
308}
309#if 0
310void
311main()
312{
313 char blubber[73];
314 char salt[100];
315 char *p;
316 salt[0] = '$';
317 salt[1] = BCRYPT_VERSION;
318 salt[2] = '$';
319
320 snprintf(salt + 3, 4, "%2.2u$", 5);
321
322 printf("24 bytes of salt: ");
323 fgets(salt + 6, sizeof(salt) - 6, stdin);
324 salt[99] = 0;
325 printf("72 bytes of password: ");
326 fpurge(stdin);
327 fgets(blubber, sizeof(blubber), stdin);
328 blubber[72] = 0;
329
330 p = crypt(blubber, salt);
331 printf("Passwd entry: %s\n\n", p);
332
333 p = bcrypt_gensalt(5);
334 printf("Generated salt: %s\n", p);
335 p = crypt(blubber, p);
336 printf("Passwd entry: %s\n", p);
337}
338#endif
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3
new file mode 100644
index 0000000000..4defaecc34
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: blowfish.3,v 1.20 2007/05/31 19:19:27 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: May 31 2007 $
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.Fd #include <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
63is a fast unpatented block cipher designed by Bruce Schneier.
64It basically consists of a 16-round Feistel network.
65The block size is 64 bits and the maximum key size is 448 bits.
66.Pp
67The
68.Fn blf_key
69function initializes the 4 8-bit S-boxes and the 18 Subkeys with
70the hexadecimal digits of Pi.
71The key is used for further randomization.
72The first argument to
73.Fn blf_enc
74is the initialized state derived from
75.Fn blf_key .
76The stream of 32-bit words is encrypted in Electronic Codebook
77Mode (ECB) and
78.Fa blocks
79is the number of 64-bit blocks in the stream.
80.Fn blf_dec
81is used for decrypting Blowfish encrypted blocks.
82.Pp
83The functions
84.Fn blf_ecb_encrypt
85and
86.Fn blf_ecb_decrypt
87are used for encrypting and decrypting octet streams in ECB mode.
88The functions
89.Fn blf_cbc_encrypt
90and
91.Fn blf_cbc_decrypt
92are used for encrypting and decrypting octet streams in
93Cipherblock Chaining Mode (CBC).
94For these functions
95.Fa datalen
96specifies the number of octets of data to encrypt or decrypt.
97It must be a multiple of 8 (64-bit block).
98The initialisation vector
99.Fa iv
100points 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 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
66void
67Blowfish_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
91void
92Blowfish_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
116void
117Blowfish_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
395u_int32_t
396Blowfish_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
416void
417Blowfish_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
454void
455Blowfish_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
497void
498blf_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
507void
508blf_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
520void
521blf_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
533void
534blf_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
555void
556blf_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
577void
578blf_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
602void
603blf_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
644void
645report(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}
652void
653main(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/cast.c b/src/lib/libc/crypt/cast.c
new file mode 100644
index 0000000000..ea026638d6
--- /dev/null
+++ b/src/lib/libc/crypt/cast.c
@@ -0,0 +1,790 @@
1/* $OpenBSD: cast.c,v 1.3 2004/11/03 10:38:50 hshoexer Exp $ */
2/*
3 * CAST-128 in C
4 * Written by Steve Reid <sreid@sea-to-sky.net>
5 * 100% Public Domain - no warranty
6 * Released 1997.10.11
7 */
8
9#include <sys/types.h>
10
11#include <cast.h>
12
13/* CAST S-Boxes */
14
15static const u_int32_t cast_sbox1[256] = {
16 0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A,
17 0x1E213F2F, 0x9C004DD3, 0x6003E540, 0xCF9FC949,
18 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
19 0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E,
20 0x28683B6F, 0xC07FD059, 0xFF2379C8, 0x775F50E2,
21 0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
22 0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
23 0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
24 0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
25 0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
26 0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
27 0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
28 0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
29 0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
30 0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
31 0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
32 0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
33 0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
34 0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
35 0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
36 0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
37 0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
38 0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
39 0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
40 0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
41 0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
42 0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
43 0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
44 0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
45 0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
46 0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
47 0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
48 0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
49 0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
50 0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
51 0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
52 0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
53 0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
54 0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
55 0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
56 0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
57 0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
58 0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
59 0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
60 0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
61 0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
62 0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
63 0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
64 0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
65 0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
66 0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
67 0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
68 0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
69 0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
70 0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
71 0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
72 0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
73 0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
74 0x474D6AD7, 0x7C0C5E5C, 0xD1231959, 0x381B7298,
75 0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
76 0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571,
77 0x962BDA1C, 0xE1E696FF, 0xB141AB08, 0x7CCA89B9,
78 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
79 0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF
80};
81
82static const u_int32_t cast_sbox2[256] = {
83 0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380,
84 0xFE61CF7A, 0xEEC5207A, 0x55889C94, 0x72FC0651,
85 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
86 0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3,
87 0xA0B52F7B, 0x59E83605, 0xEE15B094, 0xE9FFD909,
88 0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
89 0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
90 0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
91 0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
92 0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
93 0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
94 0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
95 0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
96 0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
97 0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
98 0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
99 0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
100 0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
101 0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
102 0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
103 0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
104 0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
105 0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
106 0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
107 0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
108 0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
109 0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
110 0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
111 0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
112 0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
113 0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
114 0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
115 0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
116 0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
117 0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
118 0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
119 0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
120 0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
121 0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
122 0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
123 0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
124 0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
125 0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
126 0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
127 0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
128 0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
129 0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
130 0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
131 0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
132 0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
133 0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
134 0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
135 0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
136 0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
137 0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
138 0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
139 0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
140 0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
141 0xB284600C, 0xD835731D, 0xDCB1C647, 0xAC4C56EA,
142 0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
143 0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD,
144 0x649DA589, 0xA345415E, 0x5C038323, 0x3E5D3BB9,
145 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
146 0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1
147};
148
149static const u_int32_t cast_sbox3[256] = {
150 0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907,
151 0x47607FFF, 0x369FE44B, 0x8C1FC644, 0xAECECA90,
152 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
153 0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5,
154 0x11107D9F, 0x07647DB9, 0xB2E3E4D4, 0x3D4F285E,
155 0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
156 0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
157 0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
158 0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
159 0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
160 0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
161 0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
162 0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
163 0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
164 0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
165 0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
166 0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
167 0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
168 0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
169 0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
170 0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
171 0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
172 0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
173 0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
174 0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
175 0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
176 0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
177 0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
178 0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
179 0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
180 0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
181 0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
182 0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
183 0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
184 0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
185 0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
186 0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
187 0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
188 0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
189 0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
190 0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
191 0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
192 0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
193 0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
194 0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
195 0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
196 0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
197 0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
198 0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
199 0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
200 0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
201 0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
202 0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
203 0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
204 0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
205 0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
206 0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
207 0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
208 0x5727C148, 0x2BE98A1D, 0x8AB41738, 0x20E1BE24,
209 0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
210 0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0,
211 0x642B1E31, 0x9C305A00, 0x52BCE688, 0x1B03588A,
212 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
213 0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783
214};
215
216static const u_int32_t cast_sbox4[256] = {
217 0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298,
218 0x4A4F7BDB, 0x64AD8C57, 0x85510443, 0xFA020ED1,
219 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
220 0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF,
221 0x28147F5F, 0x4FA2B8CD, 0xC9430040, 0x0CC32220,
222 0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
223 0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
224 0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
225 0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
226 0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
227 0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
228 0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
229 0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
230 0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
231 0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
232 0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
233 0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
234 0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
235 0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
236 0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
237 0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
238 0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
239 0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
240 0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
241 0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
242 0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
243 0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
244 0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
245 0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
246 0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
247 0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
248 0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
249 0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
250 0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
251 0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
252 0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
253 0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
254 0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
255 0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
256 0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
257 0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
258 0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
259 0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
260 0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
261 0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
262 0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
263 0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
264 0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
265 0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
266 0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
267 0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
268 0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
269 0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
270 0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
271 0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
272 0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
273 0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
274 0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
275 0xB5676E69, 0x9BD3DDDA, 0xDF7E052F, 0xDB25701C,
276 0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
277 0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43,
278 0x41823979, 0x932BCDF6, 0xB657C34D, 0x4EDFD282,
279 0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
280 0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2
281};
282
283static const u_int32_t cast_sbox5[256] = {
284 0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
285 0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
286 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
287 0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
288 0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
289 0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
290 0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
291 0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
292 0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
293 0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
294 0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
295 0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
296 0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
297 0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
298 0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
299 0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
300 0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
301 0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
302 0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
303 0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
304 0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
305 0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
306 0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
307 0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
308 0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
309 0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
310 0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
311 0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
312 0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
313 0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
314 0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
315 0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
316 0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
317 0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
318 0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
319 0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
320 0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
321 0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
322 0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
323 0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
324 0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
325 0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
326 0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
327 0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
328 0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
329 0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
330 0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
331 0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
332 0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
333 0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
334 0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
335 0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
336 0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
337 0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
338 0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
339 0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
340 0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
341 0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
342 0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
343 0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
344 0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
345 0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
346 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
347 0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
348};
349
350static const u_int32_t cast_sbox6[256] = {
351 0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
352 0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
353 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
354 0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
355 0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
356 0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
357 0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
358 0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
359 0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
360 0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
361 0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
362 0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
363 0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
364 0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
365 0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
366 0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
367 0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
368 0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
369 0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
370 0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
371 0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
372 0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
373 0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
374 0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
375 0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
376 0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
377 0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
378 0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
379 0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
380 0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
381 0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
382 0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
383 0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
384 0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
385 0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
386 0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
387 0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
388 0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
389 0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
390 0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
391 0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
392 0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
393 0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
394 0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
395 0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
396 0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
397 0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
398 0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
399 0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
400 0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
401 0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
402 0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
403 0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
404 0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
405 0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
406 0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
407 0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
408 0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
409 0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
410 0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
411 0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
412 0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
413 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
414 0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
415};
416
417static const u_int32_t cast_sbox7[256] = {
418 0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
419 0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
420 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
421 0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
422 0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
423 0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
424 0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
425 0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
426 0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
427 0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
428 0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
429 0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
430 0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
431 0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
432 0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
433 0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
434 0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
435 0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
436 0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
437 0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
438 0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
439 0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
440 0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
441 0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
442 0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
443 0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
444 0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
445 0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
446 0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
447 0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
448 0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
449 0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
450 0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
451 0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
452 0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
453 0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
454 0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
455 0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
456 0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
457 0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
458 0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
459 0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
460 0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
461 0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
462 0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
463 0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
464 0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
465 0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
466 0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
467 0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
468 0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
469 0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
470 0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
471 0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
472 0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
473 0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
474 0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
475 0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
476 0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
477 0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
478 0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
479 0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
480 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
481 0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
482};
483
484static const u_int32_t cast_sbox8[256] = {
485 0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
486 0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
487 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
488 0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
489 0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
490 0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
491 0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
492 0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
493 0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
494 0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
495 0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
496 0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
497 0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
498 0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
499 0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
500 0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
501 0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
502 0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
503 0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
504 0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
505 0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
506 0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
507 0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
508 0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
509 0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
510 0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
511 0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
512 0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
513 0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
514 0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
515 0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
516 0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
517 0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
518 0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
519 0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
520 0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
521 0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
522 0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
523 0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
524 0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
525 0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
526 0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
527 0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
528 0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
529 0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
530 0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
531 0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
532 0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
533 0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
534 0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
535 0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
536 0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
537 0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
538 0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
539 0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
540 0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
541 0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
542 0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
543 0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
544 0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
545 0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
546 0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
547 0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
548 0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
549};
550
551/* Macros to access 8-bit bytes out of a 32-bit word */
552#define U8a(x) ( (u_int8_t) (x>>24) )
553#define U8b(x) ( (u_int8_t) ((x>>16)&255) )
554#define U8c(x) ( (u_int8_t) ((x>>8)&255) )
555#define U8d(x) ( (u_int8_t) ((x)&255) )
556
557/* Circular left shift */
558#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
559
560/* CAST-128 uses three different round functions */
561#define F1(l, r, i) \
562 t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
563 l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) - \
564 cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
565#define F2(l, r, i) \
566 t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
567 l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) + \
568 cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
569#define F3(l, r, i) \
570 t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
571 l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) ^ \
572 cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
573
574
575/***** Encryption Function *****/
576
577void
578cast_encrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
579{
580 u_int32_t t, l, r;
581
582 /* Get inblock into l,r */
583 l = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
584 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
585 r = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
586 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
587 /* Do the work */
588 F1(l, r, 0);
589 F2(r, l, 1);
590 F3(l, r, 2);
591 F1(r, l, 3);
592 F2(l, r, 4);
593 F3(r, l, 5);
594 F1(l, r, 6);
595 F2(r, l, 7);
596 F3(l, r, 8);
597 F1(r, l, 9);
598 F2(l, r, 10);
599 F3(r, l, 11);
600 /* Only do full 16 rounds if key length > 80 bits */
601 if (key->rounds > 12) {
602 F1(l, r, 12);
603 F2(r, l, 13);
604 F3(l, r, 14);
605 F1(r, l, 15);
606 }
607 /* Put l,r into outblock */
608 outblock[0] = U8a(r);
609 outblock[1] = U8b(r);
610 outblock[2] = U8c(r);
611 outblock[3] = U8d(r);
612 outblock[4] = U8a(l);
613 outblock[5] = U8b(l);
614 outblock[6] = U8c(l);
615 outblock[7] = U8d(l);
616 /* Wipe clean */
617 t = l = r = 0;
618}
619
620
621/***** Decryption Function *****/
622
623void
624cast_decrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
625{
626 u_int32_t t, l, r;
627
628 /* Get inblock into l,r */
629 r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
630 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
631 l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
632 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
633 /* Do the work */
634 /* Only do full 16 rounds if key length > 80 bits */
635 if (key->rounds > 12) {
636 F1(r, l, 15);
637 F3(l, r, 14);
638 F2(r, l, 13);
639 F1(l, r, 12);
640 }
641 F3(r, l, 11);
642 F2(l, r, 10);
643 F1(r, l, 9);
644 F3(l, r, 8);
645 F2(r, l, 7);
646 F1(l, r, 6);
647 F3(r, l, 5);
648 F2(l, r, 4);
649 F1(r, l, 3);
650 F3(l, r, 2);
651 F2(r, l, 1);
652 F1(l, r, 0);
653 /* Put l,r into outblock */
654 outblock[0] = U8a(l);
655 outblock[1] = U8b(l);
656 outblock[2] = U8c(l);
657 outblock[3] = U8d(l);
658 outblock[4] = U8a(r);
659 outblock[5] = U8b(r);
660 outblock[6] = U8c(r);
661 outblock[7] = U8d(r);
662 /* Wipe clean */
663 t = l = r = 0;
664}
665
666
667/***** Key Schedual *****/
668
669void
670cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes)
671{
672 u_int32_t t[4], z[4], x[4];
673 int i;
674
675 /* Set number of rounds to 12 or 16, depending on key length */
676 key->rounds = (keybytes <= 10 ? 12 : 16);
677
678 /* Copy key to workspace x */
679 for (i = 0; i < 4; i++) {
680 x[i] = 0;
681 if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
682 if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
683 if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
684 if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
685 }
686 /* Generate 32 subkeys, four at a time */
687 for (i = 0; i < 32; i+=4) {
688 switch (i & 4) {
689 case 0:
690 t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])] ^
691 cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])] ^
692 cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])];
693 t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])] ^
694 cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])] ^
695 cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])];
696 t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])] ^
697 cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])] ^
698 cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])];
699 t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^
700 cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])] ^
701 cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])];
702 break;
703 case 4:
704 t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])] ^
705 cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])] ^
706 cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])];
707 t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])] ^
708 cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])] ^
709 cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])];
710 t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])] ^
711 cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])] ^
712 cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])];
713 t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])] ^
714 cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])] ^
715 cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])];
716 break;
717 }
718 switch (i & 12) {
719 case 0:
720 case 12:
721 key->xkey[i+0] = cast_sbox5[U8a(t[2])] ^
722 cast_sbox6[U8b(t[2])] ^ cast_sbox7[U8d(t[1])] ^
723 cast_sbox8[U8c(t[1])];
724 key->xkey[i+1] = cast_sbox5[U8c(t[2])] ^
725 cast_sbox6[U8d(t[2])] ^ cast_sbox7[U8b(t[1])] ^
726 cast_sbox8[U8a(t[1])];
727 key->xkey[i+2] = cast_sbox5[U8a(t[3])] ^
728 cast_sbox6[U8b(t[3])] ^ cast_sbox7[U8d(t[0])] ^
729 cast_sbox8[U8c(t[0])];
730 key->xkey[i+3] = cast_sbox5[U8c(t[3])] ^
731 cast_sbox6[U8d(t[3])] ^ cast_sbox7[U8b(t[0])] ^
732 cast_sbox8[U8a(t[0])];
733 break;
734 case 4:
735 case 8:
736 key->xkey[i+0] = cast_sbox5[U8d(t[0])] ^
737 cast_sbox6[U8c(t[0])] ^ cast_sbox7[U8a(t[3])] ^
738 cast_sbox8[U8b(t[3])];
739 key->xkey[i+1] = cast_sbox5[U8b(t[0])] ^
740 cast_sbox6[U8a(t[0])] ^ cast_sbox7[U8c(t[3])] ^
741 cast_sbox8[U8d(t[3])];
742 key->xkey[i+2] = cast_sbox5[U8d(t[1])] ^
743 cast_sbox6[U8c(t[1])] ^ cast_sbox7[U8a(t[2])] ^
744 cast_sbox8[U8b(t[2])];
745 key->xkey[i+3] = cast_sbox5[U8b(t[1])] ^
746 cast_sbox6[U8a(t[1])] ^ cast_sbox7[U8c(t[2])] ^
747 cast_sbox8[U8d(t[2])];
748 break;
749 }
750 switch (i & 12) {
751 case 0:
752 key->xkey[i+0] ^= cast_sbox5[U8c(z[0])];
753 key->xkey[i+1] ^= cast_sbox6[U8c(z[1])];
754 key->xkey[i+2] ^= cast_sbox7[U8b(z[2])];
755 key->xkey[i+3] ^= cast_sbox8[U8a(z[3])];
756 break;
757 case 4:
758 key->xkey[i+0] ^= cast_sbox5[U8a(x[2])];
759 key->xkey[i+1] ^= cast_sbox6[U8b(x[3])];
760 key->xkey[i+2] ^= cast_sbox7[U8d(x[0])];
761 key->xkey[i+3] ^= cast_sbox8[U8d(x[1])];
762 break;
763 case 8:
764 key->xkey[i+0] ^= cast_sbox5[U8b(z[2])];
765 key->xkey[i+1] ^= cast_sbox6[U8a(z[3])];
766 key->xkey[i+2] ^= cast_sbox7[U8c(z[0])];
767 key->xkey[i+3] ^= cast_sbox8[U8c(z[1])];
768 break;
769 case 12:
770 key->xkey[i+0] ^= cast_sbox5[U8d(x[0])];
771 key->xkey[i+1] ^= cast_sbox6[U8d(x[1])];
772 key->xkey[i+2] ^= cast_sbox7[U8a(x[2])];
773 key->xkey[i+3] ^= cast_sbox8[U8b(x[3])];
774 break;
775 }
776 if (i >= 16) {
777 key->xkey[i+0] &= 31;
778 key->xkey[i+1] &= 31;
779 key->xkey[i+2] &= 31;
780 key->xkey[i+3] &= 31;
781 }
782 }
783 /* Wipe clean */
784 for (i = 0; i < 4; i++) {
785 t[i] = x[i] = z[i] = 0;
786 }
787}
788
789/* Made in Canada */
790
diff --git a/src/lib/libc/crypt/crypt.3 b/src/lib/libc/crypt/crypt.3
new file mode 100644
index 0000000000..b58894d9ad
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.3
@@ -0,0 +1,324 @@
1.\" $OpenBSD: crypt.3,v 1.27 2007/10/08 11:55:27 pyr 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: October 8 2007 $
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 DES encryption
47.Sh SYNOPSIS
48.Fd #include <pwd.h>
49.Fd #include <unistd.h>
50.Ft char *
51.Fn crypt "const char *key" "const char *setting"
52.Ft int
53.Fn setkey "const char *key"
54.Ft int
55.Fn encrypt "char *block" "int flag"
56.Ft int
57.Fn des_setkey "const char *key"
58.Ft int
59.Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count"
60.Ft char *
61.Fn bcrypt_gensalt "u_int8_t log_rounds"
62.Ft char *
63.Fn bcrypt "const char *key" "const char *salt"
64.Ft char *
65.Fn md5crypt "const char *key" "const char *salt"
66.Sh DESCRIPTION
67The
68.Fn crypt
69function performs password encryption based on the
70.Tn NBS
71Data Encryption Standard (DES).
72Additional code has been added to deter key search attempts and to use
73stronger hashing algorithms.
74.Pp
75The first argument to
76.Fn crypt
77is a
78.Dv NUL Ns -terminated
79string, typically a user's typed password.
80The second is in one of three forms:
81if it begins with an underscore
82.Pq Ql _
83then an extended format is used
84in interpreting both the key and the setting, as outlined below.
85If it begins
86with a string character
87.Pq Ql $
88and a number then a different algorithm is used depending on the number.
89At the moment a
90.Ql $1
91chooses MD5 hashing and a
92.Ql $2
93chooses Blowfish hashing; see below for more information.
94.Ss Extended crypt
95The
96.Ar key
97is divided into groups of 8 characters (the last group is null-padded)
98and the low-order 7 bits of each character (56 bits per group) are
99used to form the DES key as follows:
100the first group of 56 bits becomes the initial DES key.
101For each additional group, the XOR of the encryption of the current DES
102key with itself and the group bits becomes the next DES key.
103.Pp
104The setting is a 9-character array consisting of an underscore followed
105by 4 bytes of iteration count and 4 bytes of salt.
106These are encoded as printable characters, 6 bits per character,
107least significant character first.
108The values 0 to 63 are encoded as
109.Dq \&./0-9A-Za-z .
110This allows 24 bits for both
111.Fa count
112and
113.Fa salt .
114.Ss "MD5" crypt
115For
116.Tn MD5
117crypt the version number,
118.Fa salt
119and the hashed password are separated by the
120.Ql $
121character.
122The maximum length of a password is limited by
123the length counter of the MD5 context, which is about
1242**64.
125A valid MD5 password entry looks like this:
126.Pp
127.Dq $1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1 .
128.Pp
129The whole MD5 password string is passed as
130.Fa setting
131for interpretation.
132.Ss "Blowfish" crypt
133The
134.Tn Blowfish
135version of crypt has 128 bits of
136.Fa salt
137in order to make building dictionaries of common passwords space consuming.
138The initial state of the
139.Tn Blowfish
140cipher is expanded using the
141.Fa salt
142and the
143.Fa password
144repeating the process a variable number of rounds, which is encoded in
145the password string.
146The maximum password length is 72.
147The final Blowfish password entry is created by encrypting the string
148.Pp
149.Dq OrpheanBeholderScryDoubt
150.Pp
151with the
152.Tn Blowfish
153state 64 times.
154.Pp
155The version number, the logarithm of the number of rounds and
156the concatenation of salt and hashed password are separated by the
157.Ql $
158character.
159An encoded
160.Sq 8
161would specify 256 rounds.
162A valid Blowfish password looks like this:
163.Pp
164.Dq $2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC .
165.Pp
166The whole Blowfish password string is passed as
167.Fa setting
168for interpretation.
169.Ss "Traditional" crypt
170The first 8 bytes of the key are null-padded, and the low-order 7 bits of
171each character is used to form the 56-bit
172.Tn DES
173key.
174.Pp
175The setting is a 2-character array of the ASCII-encoded salt.
176Thus only 12 bits of
177.Fa salt
178are used.
179.Fa count
180is set to 25.
181.Ss DES Algorithm
182The
183.Fa salt
184introduces disorder in the
185.Tn DES
186algorithm in one of 16777216 or 4096 possible ways
187(i.e., with 24 or 12 bits: if bit
188.Em i
189of the
190.Ar salt
191is set, then bits
192.Em i
193and
194.Em i+24
195are swapped in the
196.Tn DES
197E-box output).
198.Pp
199The DES key is used to encrypt a 64-bit constant using
200.Ar count
201iterations of
202.Tn DES .
203The value returned is a
204.Dv NUL Ns -terminated
205string, 20 or 13 bytes (plus NUL) in length, consisting of the
206.Ar setting
207followed by the encoded 64-bit encryption.
208.Pp
209The functions
210.Fn encrypt ,
211.Fn setkey ,
212.Fn des_setkey ,
213and
214.Fn des_cipher
215provide access to the
216.Tn DES
217algorithm itself.
218.Fn setkey
219is passed a 64-byte array of binary values (numeric 0 or 1).
220A 56-bit key is extracted from this array by dividing the
221array into groups of 8, and ignoring the last bit in each group.
222That bit is reserved for a byte parity check by DES, but is ignored
223by these functions.
224.Pp
225The
226.Fa block
227argument to
228.Fn encrypt
229is also a 64-byte array of binary values.
230If the value of
231.Fa flag
232is 0,
233.Fa block
234is encrypted otherwise it is decrypted.
235The result is returned in the original array
236.Fa block
237after using the key specified by
238.Fn setkey
239to process it.
240.Pp
241The argument to
242.Fn des_setkey
243is a character array of length 8.
244The least significant bit (the parity bit) in each character is ignored,
245and the remaining bits are concatenated to form a 56-bit key.
246The function
247.Fn des_cipher
248encrypts (or decrypts if
249.Fa count
250is negative) the 64-bits stored in the 8 characters at
251.Fa in
252using
253.Xr abs 3
254of
255.Fa count
256iterations of
257.Tn DES
258and stores the 64-bit result in the 8 characters at
259.Fa out
260(which may be the same as
261.Fa in ) .
262The
263.Fa salt
264specifies perturbations to the
265.Tn DES
266E-box output as described above.
267.Pp
268The
269.Fn crypt ,
270.Fn setkey ,
271and
272.Fn des_setkey
273functions all manipulate the same key space.
274.Sh RETURN VALUES
275The function
276.Fn crypt
277returns a pointer to the encrypted value on success, and
278.Dv NULL
279on failure.
280The functions
281.Fn setkey ,
282.Fn encrypt ,
283.Fn des_setkey ,
284and
285.Fn des_cipher
286return 0 on success and 1 on failure.
287.Sh SEE ALSO
288.Xr login 1 ,
289.Xr passwd 1 ,
290.Xr blowfish 3 ,
291.Xr getpass 3 ,
292.Xr md5 3 ,
293.Xr passwd 5
294.Sh HISTORY
295A rotor-based
296.Fn crypt
297function appeared in
298.At v3 .
299The current style
300.Fn crypt
301first appeared in
302.At v7 .
303.Pp
304This library (FreeSec 1.0) was developed outside the United States of America
305as an unencumbered replacement for the U.S.-only libcrypt encryption
306library.
307Programs linked against the
308.Fn crypt
309interface may be exported from the U.S.A. only if they use
310.Fn crypt
311solely for authentication purposes and avoid use of
312the other programmer interfaces listed above.
313Special care has been taken
314in the library so that programs which only use the
315.Fn crypt
316interface do not pull in the other components.
317.Sh AUTHORS
318.An David Burren Aq davidb@werj.com.au
319.Sh BUGS
320The
321.Fn crypt
322function returns a pointer to static data, and subsequent calls to
323.Fn crypt
324will modify the same object.
diff --git a/src/lib/libc/crypt/crypt.c b/src/lib/libc/crypt/crypt.c
new file mode 100644
index 0000000000..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
59static 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
66static u_char inv_key_perm[64];
67static u_char u_key_perm[56];
68static 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
75static 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
79static u_char inv_comp_perm[56];
80static 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
91static u_char u_sbox[8][64];
92static 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
143static u_char un_pbox[32];
144static 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
149const 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
161const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
162
163static u_int32_t saltbits;
164static int32_t old_salt;
165static const u_int32_t *bits28, *bits24;
166static u_char init_perm[64], final_perm[64];
167static u_int32_t en_keysl[16], en_keysr[16];
168static u_int32_t de_keysl[16], de_keysr[16];
169int _des_initialised = 0;
170static u_char m_sbox[4][4096];
171static u_int32_t psbox[4][256];
172static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
173static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
174static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
175static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
176static u_int32_t old_rawkey0, old_rawkey1;
177
178static u_char ascii64[] =
179 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
180/* 0000000000111111111122222222223333333333444444444455555555556666 */
181/* 0123456789012345678901234567890123456789012345678901234567890123 */
182
183static __inline int
184ascii_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
201void
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
331void
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
352int
353des_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
432int
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
549int
550des_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
572char *
573crypt(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..63a297e510
--- /dev/null
+++ b/src/lib/libc/crypt/crypt2.c
@@ -0,0 +1,104 @@
1/* $OpenBSD: crypt2.c,v 1.3 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
59extern const u_char _des_bits8[8];
60extern const u_int32_t _des_bits32[32];
61extern int _des_initialised;
62
63int
64setkey(const char *key)
65{
66 int i, j;
67 u_int32_t packed_keys[2];
68 u_char *p;
69
70 p = (u_char *) packed_keys;
71
72 for (i = 0; i < 8; i++) {
73 p[i] = 0;
74 for (j = 0; j < 8; j++)
75 if (*key++ & 1)
76 p[i] |= _des_bits8[j];
77 }
78 return(des_setkey((char *)p));
79}
80
81int
82encrypt(char *block, int flag)
83{
84 u_int32_t io[2];
85 u_char *p;
86 int i, j, retval;
87
88 if (!_des_initialised)
89 _des_init();
90
91 _des_setup_salt(0);
92 p = (u_char *)block;
93 for (i = 0; i < 2; i++) {
94 io[i] = 0L;
95 for (j = 0; j < 32; j++)
96 if (*p++ & 1)
97 io[i] |= _des_bits32[j];
98 }
99 retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
100 for (i = 0; i < 2; i++)
101 for (j = 0; j < 32; j++)
102 block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0;
103 return(retval);
104}
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c
new file mode 100644
index 0000000000..fe1393cf7c
--- /dev/null
+++ b/src/lib/libc/crypt/md5crypt.c
@@ -0,0 +1,149 @@
1/* $OpenBSD: md5crypt.c,v 1.14 2005/08/08 08:05:33 espie Exp $ */
2
3/*
4 * ----------------------------------------------------------------------------
5 * "THE BEER-WARE LICENSE" (Revision 42):
6 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
7 * can do whatever you want with this stuff. If we meet some day, and you think
8 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
9 * ----------------------------------------------------------------------------
10 *
11 * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
12 *
13 */
14
15#include <unistd.h>
16#include <stdio.h>
17#include <string.h>
18#include <md5.h>
19#include <string.h>
20
21static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
22 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
23
24static void to64(char *, u_int32_t, int);
25
26static void
27to64(char *s, u_int32_t v, int n)
28{
29 while (--n >= 0) {
30 *s++ = itoa64[v&0x3f];
31 v >>= 6;
32 }
33}
34
35/*
36 * UNIX password
37 *
38 * Use MD5 for what it is best at...
39 */
40
41char *md5crypt(const char *pw, const char *salt);
42
43char *
44md5crypt(const char *pw, const char *salt)
45{
46 /*
47 * This string is magic for this algorithm. Having
48 * it this way, we can get get better later on
49 */
50 static unsigned char *magic = (unsigned char *)"$1$";
51
52 static char passwd[120], *p;
53 static const unsigned char *sp,*ep;
54 unsigned char final[16];
55 int sl,pl,i;
56 MD5_CTX ctx,ctx1;
57 u_int32_t l;
58
59 /* Refine the Salt first */
60 sp = (const unsigned char *)salt;
61
62 /* If it starts with the magic string, then skip that */
63 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
64 sp += strlen((const char *)magic);
65
66 /* It stops at the first '$', max 8 chars */
67 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
68 continue;
69
70 /* get the length of the true salt */
71 sl = ep - sp;
72
73 MD5Init(&ctx);
74
75 /* The password first, since that is what is most unknown */
76 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
77
78 /* Then our magic string */
79 MD5Update(&ctx,magic,strlen((const char *)magic));
80
81 /* Then the raw salt */
82 MD5Update(&ctx,sp,sl);
83
84 /* Then just as many characters of the MD5(pw,salt,pw) */
85 MD5Init(&ctx1);
86 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
87 MD5Update(&ctx1,sp,sl);
88 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
89 MD5Final(final,&ctx1);
90 for(pl = strlen(pw); pl > 0; pl -= 16)
91 MD5Update(&ctx,final,pl>16 ? 16 : pl);
92
93 /* Don't leave anything around in vm they could use. */
94 memset(final,0,sizeof final);
95
96 /* Then something really weird... */
97 for (i = strlen(pw); i ; i >>= 1)
98 if(i&1)
99 MD5Update(&ctx, final, 1);
100 else
101 MD5Update(&ctx, (const unsigned char *)pw, 1);
102
103 /* Now make the output string */
104 snprintf(passwd, sizeof(passwd), "%s%.*s$", (char *)magic,
105 sl, (const char *)sp);
106
107 MD5Final(final,&ctx);
108
109 /*
110 * and now, just to make sure things don't run too fast
111 * On a 60 Mhz Pentium this takes 34 msec, so you would
112 * need 30 seconds to build a 1000 entry dictionary...
113 */
114 for(i=0;i<1000;i++) {
115 MD5Init(&ctx1);
116 if(i & 1)
117 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
118 else
119 MD5Update(&ctx1,final,16);
120
121 if(i % 3)
122 MD5Update(&ctx1,sp,sl);
123
124 if(i % 7)
125 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
126
127 if(i & 1)
128 MD5Update(&ctx1,final,16);
129 else
130 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
131 MD5Final(final,&ctx1);
132 }
133
134 p = passwd + strlen(passwd);
135
136 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
137 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
138 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
139 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
140 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
141 l = final[11] ; to64(p,l,2); p += 2;
142 *p = '\0';
143
144 /* Don't leave anything around in vm they could use. */
145 memset(final, 0, sizeof final);
146
147 return passwd;
148}
149
diff --git a/src/lib/libc/crypt/skipjack.c b/src/lib/libc/crypt/skipjack.c
new file mode 100644
index 0000000000..2212b984bb
--- /dev/null
+++ b/src/lib/libc/crypt/skipjack.c
@@ -0,0 +1,260 @@
1/* $OpenBSD: skipjack.c,v 1.3 2004/10/01 04:08:45 jsg Exp $ */
2
3/*
4 * Further optimized test implementation of SKIPJACK algorithm
5 * Mark Tillotson <markt@chaos.org.uk>, 25 June 98
6 * Optimizations suit RISC (lots of registers) machine best.
7 *
8 * based on unoptimized implementation of
9 * Panu Rissanen <bande@lut.fi> 960624
10 *
11 * SKIPJACK and KEA Algorithm Specifications
12 * Version 2.0
13 * 29 May 1998
14*/
15
16#include <sys/param.h>
17#include <skipjack.h>
18#include <stdlib.h>
19
20static const u_int8_t ftable[0x100] =
21{
22 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4,
23 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9,
24 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e,
25 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28,
26 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68,
27 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53,
28 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19,
29 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2,
30 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b,
31 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8,
32 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0,
33 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90,
34 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69,
35 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76,
36 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20,
37 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d,
38 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43,
39 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18,
40 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa,
41 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4,
42 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87,
43 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40,
44 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b,
45 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5,
46 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0,
47 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2,
48 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1,
49 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8,
50 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5,
51 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac,
52 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3,
53 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46
54};
55
56/*
57 * For each key byte generate a table to represent the function
58 * ftable [in ^ keybyte]
59 *
60 * These tables used to save an XOR in each stage of the G-function
61 * the tables are hopefully pointed to by register allocated variables
62 * k0, k1..k9
63 */
64void
65subkey_table_gen (u_int8_t *key, u_int8_t **key_tables)
66{
67 int i, k;
68
69 for (k = 0; k < 10; k++) {
70 u_int8_t key_byte = key[k];
71 u_int8_t * table = (u_int8_t *) malloc(0x100);
72 /* XXX */
73
74 key_tables[k] = table;
75 for (i = 0; i < 0x100; i++)
76 table[i] = ftable[i ^ key_byte];
77 }
78}
79
80
81#define g(k0, k1, k2, k3, ih, il, oh, ol) \
82{ \
83 oh = k##k0 [il] ^ ih; \
84 ol = k##k1 [oh] ^ il; \
85 oh = k##k2 [ol] ^ oh; \
86 ol = k##k3 [oh] ^ ol; \
87}
88
89#define g0(ih, il, oh, ol) g(0, 1, 2, 3, ih, il, oh, ol)
90#define g4(ih, il, oh, ol) g(4, 5, 6, 7, ih, il, oh, ol)
91#define g8(ih, il, oh, ol) g(8, 9, 0, 1, ih, il, oh, ol)
92#define g2(ih, il, oh, ol) g(2, 3, 4, 5, ih, il, oh, ol)
93#define g6(ih, il, oh, ol) g(6, 7, 8, 9, ih, il, oh, ol)
94
95
96#define g_inv(k0, k1, k2, k3, ih, il, oh, ol) \
97{ \
98 ol = k##k3 [ih] ^ il; \
99 oh = k##k2 [ol] ^ ih; \
100 ol = k##k1 [oh] ^ ol; \
101 oh = k##k0 [ol] ^ oh; \
102}
103
104
105#define g0_inv(ih, il, oh, ol) g_inv(0, 1, 2, 3, ih, il, oh, ol)
106#define g4_inv(ih, il, oh, ol) g_inv(4, 5, 6, 7, ih, il, oh, ol)
107#define g8_inv(ih, il, oh, ol) g_inv(8, 9, 0, 1, ih, il, oh, ol)
108#define g2_inv(ih, il, oh, ol) g_inv(2, 3, 4, 5, ih, il, oh, ol)
109#define g6_inv(ih, il, oh, ol) g_inv(6, 7, 8, 9, ih, il, oh, ol)
110
111/* optimized version of Skipjack algorithm
112 *
113 * the appropriate g-function is inlined for each round
114 *
115 * the data movement is minimized by rotating the names of the
116 * variables w1..w4, not their contents (saves 3 moves per round)
117 *
118 * the loops are completely unrolled (needed to staticize choice of g)
119 *
120 * compiles to about 470 instructions on a Sparc (gcc -O)
121 * which is about 58 instructions per byte, 14 per round.
122 * gcc seems to leave in some unnecessary and with 0xFF operations
123 * but only in the latter part of the functions. Perhaps it
124 * runs out of resources to properly optimize long inlined function?
125 * in theory should get about 11 instructions per round, not 14
126 */
127
128void
129skipjack_forwards(u_int8_t *plain, u_int8_t *cipher, u_int8_t **key_tables)
130{
131 u_int8_t wh1 = plain[0]; u_int8_t wl1 = plain[1];
132 u_int8_t wh2 = plain[2]; u_int8_t wl2 = plain[3];
133 u_int8_t wh3 = plain[4]; u_int8_t wl3 = plain[5];
134 u_int8_t wh4 = plain[6]; u_int8_t wl4 = plain[7];
135
136 u_int8_t * k0 = key_tables [0];
137 u_int8_t * k1 = key_tables [1];
138 u_int8_t * k2 = key_tables [2];
139 u_int8_t * k3 = key_tables [3];
140 u_int8_t * k4 = key_tables [4];
141 u_int8_t * k5 = key_tables [5];
142 u_int8_t * k6 = key_tables [6];
143 u_int8_t * k7 = key_tables [7];
144 u_int8_t * k8 = key_tables [8];
145 u_int8_t * k9 = key_tables [9];
146
147 /* first 8 rounds */
148 g0 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 1; wh4 ^= wh1;
149 g4 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 2; wh3 ^= wh4;
150 g8 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 3; wh2 ^= wh3;
151 g2 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 4; wh1 ^= wh2;
152 g6 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 5; wh4 ^= wh1;
153 g0 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 6; wh3 ^= wh4;
154 g4 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 7; wh2 ^= wh3;
155 g8 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 8; wh1 ^= wh2;
156
157 /* second 8 rounds */
158 wh2 ^= wh1; wl2 ^= wl1 ^ 9 ; g2 (wh1,wl1, wh1,wl1);
159 wh1 ^= wh4; wl1 ^= wl4 ^ 10; g6 (wh4,wl4, wh4,wl4);
160 wh4 ^= wh3; wl4 ^= wl3 ^ 11; g0 (wh3,wl3, wh3,wl3);
161 wh3 ^= wh2; wl3 ^= wl2 ^ 12; g4 (wh2,wl2, wh2,wl2);
162 wh2 ^= wh1; wl2 ^= wl1 ^ 13; g8 (wh1,wl1, wh1,wl1);
163 wh1 ^= wh4; wl1 ^= wl4 ^ 14; g2 (wh4,wl4, wh4,wl4);
164 wh4 ^= wh3; wl4 ^= wl3 ^ 15; g6 (wh3,wl3, wh3,wl3);
165 wh3 ^= wh2; wl3 ^= wl2 ^ 16; g0 (wh2,wl2, wh2,wl2);
166
167 /* third 8 rounds */
168 g4 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 17; wh4 ^= wh1;
169 g8 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 18; wh3 ^= wh4;
170 g2 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 19; wh2 ^= wh3;
171 g6 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 20; wh1 ^= wh2;
172 g0 (wh1,wl1, wh1,wl1); wl4 ^= wl1 ^ 21; wh4 ^= wh1;
173 g4 (wh4,wl4, wh4,wl4); wl3 ^= wl4 ^ 22; wh3 ^= wh4;
174 g8 (wh3,wl3, wh3,wl3); wl2 ^= wl3 ^ 23; wh2 ^= wh3;
175 g2 (wh2,wl2, wh2,wl2); wl1 ^= wl2 ^ 24; wh1 ^= wh2;
176
177 /* last 8 rounds */
178 wh2 ^= wh1; wl2 ^= wl1 ^ 25; g6 (wh1,wl1, wh1,wl1);
179 wh1 ^= wh4; wl1 ^= wl4 ^ 26; g0 (wh4,wl4, wh4,wl4);
180 wh4 ^= wh3; wl4 ^= wl3 ^ 27; g4 (wh3,wl3, wh3,wl3);
181 wh3 ^= wh2; wl3 ^= wl2 ^ 28; g8 (wh2,wl2, wh2,wl2);
182 wh2 ^= wh1; wl2 ^= wl1 ^ 29; g2 (wh1,wl1, wh1,wl1);
183 wh1 ^= wh4; wl1 ^= wl4 ^ 30; g6 (wh4,wl4, wh4,wl4);
184 wh4 ^= wh3; wl4 ^= wl3 ^ 31; g0 (wh3,wl3, wh3,wl3);
185 wh3 ^= wh2; wl3 ^= wl2 ^ 32; g4 (wh2,wl2, wh2,wl2);
186
187 /* pack into byte vector */
188 cipher [0] = wh1; cipher [1] = wl1;
189 cipher [2] = wh2; cipher [3] = wl2;
190 cipher [4] = wh3; cipher [5] = wl3;
191 cipher [6] = wh4; cipher [7] = wl4;
192}
193
194
195void
196skipjack_backwards (u_int8_t *cipher, u_int8_t *plain, u_int8_t **key_tables)
197{
198 /* setup 4 16-bit portions */
199 u_int8_t wh1 = cipher[0]; u_int8_t wl1 = cipher[1];
200 u_int8_t wh2 = cipher[2]; u_int8_t wl2 = cipher[3];
201 u_int8_t wh3 = cipher[4]; u_int8_t wl3 = cipher[5];
202 u_int8_t wh4 = cipher[6]; u_int8_t wl4 = cipher[7];
203
204 u_int8_t * k0 = key_tables [0];
205 u_int8_t * k1 = key_tables [1];
206 u_int8_t * k2 = key_tables [2];
207 u_int8_t * k3 = key_tables [3];
208 u_int8_t * k4 = key_tables [4];
209 u_int8_t * k5 = key_tables [5];
210 u_int8_t * k6 = key_tables [6];
211 u_int8_t * k7 = key_tables [7];
212 u_int8_t * k8 = key_tables [8];
213 u_int8_t * k9 = key_tables [9];
214
215 /* first 8 rounds */
216 g4_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 32; wh3 ^= wh2;
217 g0_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 31; wh4 ^= wh3;
218 g6_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 30; wh1 ^= wh4;
219 g2_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 29; wh2 ^= wh1;
220 g8_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 28; wh3 ^= wh2;
221 g4_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 27; wh4 ^= wh3;
222 g0_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 26; wh1 ^= wh4;
223 g6_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 25; wh2 ^= wh1;
224
225 /* second 8 rounds */
226 wh1 ^= wh2; wl1 ^= wl2 ^ 24; g2_inv (wh2,wl2, wh2,wl2);
227 wh2 ^= wh3; wl2 ^= wl3 ^ 23; g8_inv (wh3,wl3, wh3,wl3);
228 wh3 ^= wh4; wl3 ^= wl4 ^ 22; g4_inv (wh4,wl4, wh4,wl4);
229 wh4 ^= wh1; wl4 ^= wl1 ^ 21; g0_inv (wh1,wl1, wh1,wl1);
230 wh1 ^= wh2; wl1 ^= wl2 ^ 20; g6_inv (wh2,wl2, wh2,wl2);
231 wh2 ^= wh3; wl2 ^= wl3 ^ 19; g2_inv (wh3,wl3, wh3,wl3);
232 wh3 ^= wh4; wl3 ^= wl4 ^ 18; g8_inv (wh4,wl4, wh4,wl4);
233 wh4 ^= wh1; wl4 ^= wl1 ^ 17; g4_inv (wh1,wl1, wh1,wl1);
234
235 /* third 8 rounds */
236 g0_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 16; wh3 ^= wh2;
237 g6_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 15; wh4 ^= wh3;
238 g2_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 14; wh1 ^= wh4;
239 g8_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 13; wh2 ^= wh1;
240 g4_inv (wh2,wl2, wh2,wl2); wl3 ^= wl2 ^ 12; wh3 ^= wh2;
241 g0_inv (wh3,wl3, wh3,wl3); wl4 ^= wl3 ^ 11; wh4 ^= wh3;
242 g6_inv (wh4,wl4, wh4,wl4); wl1 ^= wl4 ^ 10; wh1 ^= wh4;
243 g2_inv (wh1,wl1, wh1,wl1); wl2 ^= wl1 ^ 9; wh2 ^= wh1;
244
245 /* last 8 rounds */
246 wh1 ^= wh2; wl1 ^= wl2 ^ 8; g8_inv (wh2,wl2, wh2,wl2);
247 wh2 ^= wh3; wl2 ^= wl3 ^ 7; g4_inv (wh3,wl3, wh3,wl3);
248 wh3 ^= wh4; wl3 ^= wl4 ^ 6; g0_inv (wh4,wl4, wh4,wl4);
249 wh4 ^= wh1; wl4 ^= wl1 ^ 5; g6_inv (wh1,wl1, wh1,wl1);
250 wh1 ^= wh2; wl1 ^= wl2 ^ 4; g2_inv (wh2,wl2, wh2,wl2);
251 wh2 ^= wh3; wl2 ^= wl3 ^ 3; g8_inv (wh3,wl3, wh3,wl3);
252 wh3 ^= wh4; wl3 ^= wl4 ^ 2; g4_inv (wh4,wl4, wh4,wl4);
253 wh4 ^= wh1; wl4 ^= wl1 ^ 1; g0_inv (wh1,wl1, wh1,wl1);
254
255 /* pack into byte vector */
256 plain [0] = wh1; plain [1] = wl1;
257 plain [2] = wh2; plain [3] = wl2;
258 plain [4] = wh3; plain [5] = wl3;
259 plain [6] = wh4; plain [7] = wl4;
260}
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
4extern const char _C_ctype_[];
5extern const short _C_toupper_[];
6extern 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..2d8913e482
--- /dev/null
+++ b/src/lib/libc/include/thread_private.h
@@ -0,0 +1,160 @@
1/* $OpenBSD: thread_private.h,v 1.24 2008/06/14 15:43:43 otto 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 */
18extern 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 * helper macro to make unique names in the thread namespace
38 */
39#define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name)
40
41/*
42 * helper functions that exist as (weak) null functions in libc and
43 * (strong) functions in the thread library. These functions:
44 *
45 * _thread_tag_lock:
46 * lock the mutex associated with the given tag. If the given
47 * tag is NULL a tag is first allocated.
48 *
49 * _thread_tag_unlock:
50 * unlock the mutex associated with the given tag. If the given
51 * tag is NULL a tag is first allocated.
52 *
53 * _thread_tag_storage:
54 * return a pointer to per thread instance of data associated
55 * with the given tag. If the given tag is NULL a tag is first
56 * allocated.
57 *
58 * _thread_mutex_lock:
59 * lock the given mutex. If the given mutex is NULL,
60 * rely on rthreads/pthreads implementation to initialize
61 * the mutex before locking.
62 *
63 * _thread_mutex_unlock:
64 * unlock the given mutex.
65 *
66 * _thread_mutex_destroy:
67 * destroy the given mutex.
68 */
69void _thread_tag_lock(void **);
70void _thread_tag_unlock(void **);
71void *_thread_tag_storage(void **, void *, size_t, void *);
72void _thread_mutex_lock(void **);
73void _thread_mutex_unlock(void **);
74void _thread_mutex_destroy(void **);
75
76/*
77 * Macros used in libc to access thread mutex, keys, and per thread storage.
78 * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for
79 * historical reasons. They do the same thing, define a static variable
80 * keyed by 'name' that identifies a mutex and a key to identify per thread
81 * data.
82 */
83#define _THREAD_PRIVATE_KEY(name) \
84 static void *__THREAD_NAME(name)
85#define _THREAD_PRIVATE_MUTEX(name) \
86 static void *__THREAD_NAME(name)
87#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
88 _thread_tag_lock(&(__THREAD_NAME(name)))
89#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
90 _thread_tag_unlock(&(__THREAD_NAME(name)))
91#define _THREAD_PRIVATE(keyname, storage, error) \
92 _thread_tag_storage(&(__THREAD_NAME(keyname)), &(storage), \
93 sizeof (storage), error)
94
95/*
96 * Macros used in libc to access mutexes.
97 */
98#define _MUTEX_LOCK(mutex) \
99 do { \
100 if (__isthreaded) \
101 _thread_mutex_lock(mutex); \
102 } while (0)
103#define _MUTEX_UNLOCK(mutex) \
104 do { \
105 if (__isthreaded) \
106 _thread_mutex_unlock(mutex); \
107 } while (0)
108#define _MUTEX_DESTROY(mutex) \
109 do { \
110 if (__isthreaded) \
111 _thread_mutex_destroy(mutex); \
112 } while (0)
113
114/*
115 * Resolver code is special cased in that it uses global keys.
116 */
117extern void *__THREAD_NAME(_res);
118extern void *__THREAD_NAME(_res_ext);
119extern void *__THREAD_NAME(serv_mutex);
120
121/*
122 * malloc lock/unlock prototypes and definitions
123 */
124void _thread_malloc_lock(void);
125void _thread_malloc_unlock(void);
126
127#define _MALLOC_LOCK() do { \
128 if (__isthreaded) \
129 _thread_malloc_lock(); \
130 } while (0)
131#define _MALLOC_UNLOCK() do { \
132 if (__isthreaded) \
133 _thread_malloc_unlock();\
134 } while (0)
135
136void _thread_atexit_lock(void);
137void _thread_atexit_unlock(void);
138
139#define _ATEXIT_LOCK() do { \
140 if (__isthreaded) \
141 _thread_atexit_lock(); \
142 } while (0)
143#define _ATEXIT_UNLOCK() do { \
144 if (__isthreaded) \
145 _thread_atexit_unlock();\
146 } while (0)
147
148void _thread_arc4_lock(void);
149void _thread_arc4_unlock(void);
150
151#define _ARC4_LOCK() do { \
152 if (__isthreaded) \
153 _thread_arc4_lock(); \
154 } while (0)
155#define _ARC4_UNLOCK() do { \
156 if (__isthreaded) \
157 _thread_arc4_unlock();\
158 } while (0)
159
160#endif /* _THREAD_PRIVATE_H_ */
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 2d220067e4..7599f02832 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,46 +1,101 @@
1# $NetBSD: Makefile.inc,v 1.23 1995/03/02 09:09:07 chopps Exp $ 1# $OpenBSD: Makefile.inc,v 1.44 2007/06/05 18:04:46 henning Exp $
2# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
3 2
4# net sources 3# net sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net
6 5
7SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ 6CFLAGS+=-DRESOLVSORT
8 getproto.c getprotoent.c getprotoname.c getservbyname.c \ 7
9 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ 8SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
10 inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ 9 getifaddrs.c getnameinfo.c getnetbyaddr.c getnetbyname.c getnetent.c \
11 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \ 10 getnetnamadr.c getproto.c getprotoent.c getprotoname.c \
12 res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \ 11 getservbyname.c getservbyport.c getservent.c getrrsetbyname.c \
13 send.c sethostent.c ethers.c 12 herror.c if_indextoname.c if_nameindex.c if_nametoindex.c inet_addr.c \
13 inet_lnaof.c inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
14 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c inet_pton.c \
15 linkaddr.c net_addrcmp.c nsap_addr.c \
16 rcmd.c rresvport.c recv.c res_comp.c res_data.c res_debug.c \
17 res_debug_syms.c \
18 res_init.c res_mkquery.c res_query.c res_random.c res_send.c send.c \
19 sethostent.c ethers.c rcmdsh.c
20
21# IPv6
22SRCS+= ip6opt.c rthdr.c vars6.c
14 23
15# machine-dependent net sources 24# machine-dependent net sources
16# m-d Makefile.inc must include sources for: 25# m-d Makefile.inc must include sources for:
17# htonl() htons() ntohl() ntohs() 26# htonl() htons() ntohl() ntohs()
18 27
19.include "${.CURDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc" 28.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc"
20 29
21MAN+= byteorder.3 gethostbyname.3 getnetent.3 getprotoent.3 getservent.3 \ 30MAN+= byteorder.3 ethers.3 gai_strerror.3 getaddrinfo.3 gethostbyname.3 \
22 inet.3 linkaddr.3 ns.3 rcmd.3 resolver.3 ethers.3 31 getifaddrs.3 getnameinfo.3 getnetent.3 getprotoent.3 \
32 getrrsetbyname.3 getservent.3 if_indextoname.3 inet.3 \
33 inet_net.3 inet6_option_space.3 inet6_rthdr_space.3 \
34 inet6_opt_init.3 inet6_rth_space.3 \
35 link_addr.3 net_addrcmp.3 \
36 rcmd.3 rcmdsh.3 resolver.3
23 37
24MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ 38MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
25 byteorder.3 ntohs.3 39 byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \
40 byteorder.3 htobe64.3 byteorder.3 betoh16.3 byteorder.3 betoh32.3 \
41 byteorder.3 betoh64.3 byteorder.3 htole16.3 byteorder.3 htole32.3 \
42 byteorder.3 htole64.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \
43 byteorder.3 letoh64.3 byteorder.3 swap16.3 byteorder.3 swap32.3 \
44 byteorder.3 swap64.3
26MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ 45MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
27 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 46 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3
47MLINKS+=getaddrinfo.3 freeaddrinfo.3
28MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ 48MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
29 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ 49 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
30 gethostbyname.3 herror.3 50 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \
51 gethostbyname.3 hstrerror.3
52MLINKS+=getifaddrs.3 freeifaddrs.3
31MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ 53MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
32 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 54 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
33MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ 55MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
34 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 56 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 \
57 getprotoent.3 getprotoent_r.3 getprotoent.3 getprotobyname_r.3 \
58 getprotoent.3 getprotobynumber_r.3 getprotoent.3 setprotoent_r.3 \
59 getprotoent.3 endprotoent_r.3
35MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ 60MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
36 getservent.3 getservbyport.3 getservent.3 setservent.3 61 getservent.3 getservbyport.3 getservent.3 setservent.3 \
62 getservent.3 getservent_r.3 getservent.3 getservbyname_r.3 \
63 getservent.3 getservbyport_r.3 setservent.3 setservent_r.3 \
64 setservent.3 endservent_r.3
65MLINKS+= if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
66 if_indextoname.3 if_freenameindex.3
37MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ 67MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \
38 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ 68 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 \ 69 inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \
40 inet.3 ntoa.3 70 inet.3 ntoa.3 inet.3 inet_ntop.3 inet.3 inet_pton.3
41MLINKS+=linkaddr.3 linkntoa.3 71MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3
42MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 72MLINKS+=link_addr.3 link_ntoa.3
43MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 73MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 \
74 rcmd.3 rresvport_af.3 rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3
44MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ 75MLINKS+=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 \ 76 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
46 resolver.3 res_search.3 77 resolver.3 res_search.3
78MLINKS+=getrrsetbyname.3 freerrset.3
79MLINKS+=inet6_option_space.3 inet6_option_init.3 \
80 inet6_option_space.3 inet6_option_append.3 \
81 inet6_option_space.3 inet6_option_alloc.3 \
82 inet6_option_space.3 inet6_option_next.3 \
83 inet6_option_space.3 inet6_option_find.3
84MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \
85 inet6_rthdr_space.3 inet6_rthdr_add.3 \
86 inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \
87 inet6_rthdr_space.3 inet6_rthdr_reverse.3 \
88 inet6_rthdr_space.3 inet6_rthdr_segments.3 \
89 inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
90 inet6_rthdr_space.3 inet6_rthdr_getflags.3
91MLINKS+=inet6_opt_init.3 inet6_opt_append.3 \
92 inet6_opt_init.3 inet6_opt_finish.3 \
93 inet6_opt_init.3 inet6_opt_set_val.3 \
94 inet6_opt_init.3 inet6_opt_next.3 \
95 inet6_opt_init.3 inet6_opt_find.3 \
96 inet6_opt_init.3 inet6_opt_get_val.3
97MLINKS+=inet6_rth_space.3 inet6_rth_init.3 \
98 inet6_rth_space.3 inet6_rth_add.3 \
99 inet6_rth_space.3 inet6_rth_reverse.3 \
100 inet6_rth_space.3 inet6_rth_segments.3 \
101 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..d432c48d5c
--- /dev/null
+++ b/src/lib/libc/net/base64.c
@@ -0,0 +1,308 @@
1/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto 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
59static const char Base64[] =
60 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
61static 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
126int
127b64_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
190int
191b64_pton(src, target, targsize)
192 char const *src;
193 u_char *target;
194 size_t targsize;
195{
196 int tarindex, state, ch;
197 char *pos;
198
199 state = 0;
200 tarindex = 0;
201
202 while ((ch = *src++) != '\0') {
203 if (isspace(ch)) /* Skip whitespace anywhere. */
204 continue;
205
206 if (ch == Pad64)
207 break;
208
209 pos = strchr(Base64, ch);
210 if (pos == 0) /* A non-base64 character. */
211 return (-1);
212
213 switch (state) {
214 case 0:
215 if (target) {
216 if (tarindex >= targsize)
217 return (-1);
218 target[tarindex] = (pos - Base64) << 2;
219 }
220 state = 1;
221 break;
222 case 1:
223 if (target) {
224 if (tarindex + 1 >= targsize)
225 return (-1);
226 target[tarindex] |= (pos - Base64) >> 4;
227 target[tarindex+1] = ((pos - Base64) & 0x0f)
228 << 4 ;
229 }
230 tarindex++;
231 state = 2;
232 break;
233 case 2:
234 if (target) {
235 if (tarindex + 1 >= targsize)
236 return (-1);
237 target[tarindex] |= (pos - Base64) >> 2;
238 target[tarindex+1] = ((pos - Base64) & 0x03)
239 << 6;
240 }
241 tarindex++;
242 state = 3;
243 break;
244 case 3:
245 if (target) {
246 if (tarindex >= targsize)
247 return (-1);
248 target[tarindex] |= (pos - Base64);
249 }
250 tarindex++;
251 state = 0;
252 break;
253 }
254 }
255
256 /*
257 * We are done decoding Base-64 chars. Let's see if we ended
258 * on a byte boundary, and/or with erroneous trailing characters.
259 */
260
261 if (ch == Pad64) { /* We got a pad char. */
262 ch = *src++; /* Skip it, get next. */
263 switch (state) {
264 case 0: /* Invalid = in first position */
265 case 1: /* Invalid = in second position */
266 return (-1);
267
268 case 2: /* Valid, means one byte of info */
269 /* Skip any number of spaces. */
270 for (; ch != '\0'; ch = *src++)
271 if (!isspace(ch))
272 break;
273 /* Make sure there is another trailing = sign. */
274 if (ch != Pad64)
275 return (-1);
276 ch = *src++; /* Skip the = */
277 /* Fall through to "single trailing =" case. */
278 /* FALLTHROUGH */
279
280 case 3: /* Valid, means two bytes of info */
281 /*
282 * We know this char is an =. Is there anything but
283 * whitespace after it?
284 */
285 for (; ch != '\0'; ch = *src++)
286 if (!isspace(ch))
287 return (-1);
288
289 /*
290 * Now make sure for cases 2 and 3 that the "extra"
291 * bits that slopped past the last full byte were
292 * zeros. If we don't check them, they become a
293 * subliminal channel.
294 */
295 if (target && target[tarindex] != 0)
296 return (-1);
297 }
298 } else {
299 /*
300 * We ended by seeing the end of the string. Make sure we
301 * have no partial bytes lying around.
302 */
303 if (state != 0)
304 return (-1);
305 }
306
307 return (tarindex);
308}
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3
index 701a69f688..7f22794caa 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.15 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,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: May 31 2007 $
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.Fd #include <sys/types.h>
47.Ft u_long 56.Ft u_int32_t
48.Fn htonl "u_long hostlong" 57.Fn htonl "u_int32_t host32"
49.Ft u_short 58.Ft u_int16_t
50.Fn htons "u_short hostshort" 59.Fn htons "u_int16_t host16"
51.Ft u_long 60.Ft u_int32_t
52.Fn ntohl "u_long netlong" 61.Fn ntohl "u_int32_t net32"
53.Ft u_short 62.Ft u_int16_t
54.Fn ntohs "u_short netshort" 63.Fn ntohs "u_int16_t net16"
64.Ft u_int64_t
65.Fn htobe64 "u_int64_t host64"
66.Ft u_int32_t
67.Fn htobe32 "u_int32_t host32"
68.Ft u_int16_t
69.Fn htobe16 "u_int16_t host16"
70.Ft u_int64_t
71.Fn betoh64 "u_int64_t big64"
72.Ft u_int32_t
73.Fn betoh32 "u_int32_t big32"
74.Ft u_int16_t
75.Fn betoh16 "u_int16_t big16"
76.Ft u_int64_t
77.Fn htole64 "u_int64_t host64"
78.Ft u_int32_t
79.Fn htole32 "u_int32_t host32"
80.Ft u_int16_t
81.Fn htole16 "u_int16_t host16"
82.Ft u_int64_t
83.Fn letoh64 "u_int64_t little64"
84.Ft u_int32_t
85.Fn letoh32 "u_int32_t little32"
86.Ft u_int16_t
87.Fn letoh16 "u_int16_t little16"
88.Ft u_int64_t
89.Fn swap64 "u_int32_t val64"
90.Ft u_int32_t
91.Fn swap32 "u_int32_t val32"
92.Ft u_int16_t
93.Fn swap16 "u_int16_t val16"
55.Sh DESCRIPTION 94.Sh DESCRIPTION
56These routines convert 16 and 32 bit quantities between network 95These routines convert 16, 32 and 64-bit quantities between different
96byte orderings.
97The
98.Dq swap
99functions reverse the byte ordering of
100the given quantity; the others convert either from/to the native
101byte order used by the host to/from either little- or big-endian (a.k.a
102network) order.
103.Pp
104Apart from the swap functions, the names can be described by this form:
105{src-order}to{dst-order}{size}.
106Both {src-order} and {dst-order} can take the following forms:
107.Pp
108.Bl -tag -width "be " -offset indent -compact
109.It h
110Host order.
111.It n
112Network order (big-endian).
113.It be
114Big-endian (most significant byte first).
115.It le
116Little-endian (least significant byte first).
117.El
118.Pp
119One of the specified orderings must be
120.Sq h .
121{size} will take these forms:
122.Pp
123.Bl -tag -width "32 " -offset indent -compact
124.It l
125Long (32-bit, used in conjunction with forms involving
126.Sq n ) .
127.It s
128Short (16-bit, used in conjunction with forms involving
129.Sq n ) .
130.It 16
13116-bit.
132.It 32
13332-bit.
134.It 64
13564-bit.
136.El
137.Pp
138The swap functions are of the form: swap{size}.
139.Pp
140Names involving
141.Sq n
142convert quantities between network
57byte order and host byte order. 143byte order and host byte order.
144The last letter
145.Pf ( Sq s
146or
147.Sq l )
148is a mnemonic
149for the traditional names for such quantities,
150.Li short
151and
152.Li long ,
153respectively.
154Today, the C concept of
155.Li short
156and
157.Li long
158integers need not coincide with this traditional misunderstanding.
58On machines which have a byte order which is the same as the network 159On machines which have a byte order which is the same as the network
59order, routines are defined as null macros. 160order, routines are defined as null macros.
60.Pp 161.Pp
61These routines are most often used in conjunction with Internet 162The functions involving either
62addresses and ports as returned by 163.Dq be ,
164.Dq le ,
165or
166.Dq swap
167use the numbers
16816, 32, or 64 for specifying the bitwidth of the quantities they operate on.
169Currently all supported architectures are either big- or little-endian
170so either the
171.Dq be
172or
173.Dq le
174variants are implemented as null macros.
175.Pp
176The routines mentioned above which have either {src-order} or {dst-order}
177set to
178.Sq n
179are most often used in
180conjunction with Internet addresses and ports as returned by
63.Xr gethostbyname 3 181.Xr gethostbyname 3
64and 182and
65.Xr getservent 3 . 183.Xr getservent 3 .
66.Sh SEE ALSO 184.Sh SEE ALSO
67.Xr gethostbyname 3 , 185.Xr gethostbyname 3 ,
68.Xr getservent 3 186.Xr getservent 3
187.Sh STANDARDS
188The
189.Fn htonl ,
190.Fn htons ,
191.Fn ntohl ,
192and
193.Fn ntohs
194functions conform to
195.St -p1003.1 .
196The other functions are extensions that should not be used when portability
197is required.
69.Sh HISTORY 198.Sh HISTORY
70The 199The
71.Nm byteorder 200.Nm byteorder
72functions appeared in 201functions appeared in
73.Bx 4.2 . 202.Bx 4.2 .
74.Sh BUGS 203.Sh BUGS
75On the 204On the vax, alpha, i386, and some mips architectures,
76.Tn VAX 205bytes are handled backwards from most everyone else in the world.
77bytes are handled backwards from most everyone else in 206This is not expected to be fixed in the near future.
78the world. This is not expected to be fixed in the near future.
diff --git a/src/lib/libc/net/ethers.3 b/src/lib/libc/net/ethers.3
index 81e6c65935..435a52696a 100644
--- a/src/lib/libc/net/ethers.3
+++ b/src/lib/libc/net/ethers.3
@@ -1,65 +1,85 @@
1.\" $OpenBSD: ethers.3,v 1.19 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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
16.Fd #include <sys/types.h>
17.Fd #include <sys/socket.h>
18.Fd #include <net/if.h>
19.Fd #include <netinet/in.h>
15.Fd #include <netinet/if_ether.h> 20.Fd #include <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
24Ethernet addresses are represented by the 32Ethernet addresses are represented by the
25following structure: 33following structure:
26.Bd -literal -offset indent 34.Bd -literal -offset indent
27struct ether_addr { 35struct ether_addr {
28 u_char ether_addr_octet[6]; 36 u_int8_t ether_addr_octet[6];
29}; 37};
30.Ed 38.Ed
31.Pp 39.Pp
32The 40The
33.Fn ether_ntoa 41.Fn ether_ntoa
34function converts this structure into an ASCII string of the form 42function converts this structure into an
35``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated 43.Tn ASCII
36by colons. It returns a pointer to a static buffer that is reused for 44string of the form
37each call. 45.Dq xx:xx:xx:xx:xx:xx ,
46consisting of 6 hexadecimal numbers separated
47by colons.
48It returns a pointer to a static buffer that is reused for each call.
38The 49The
39.Fn ether_aton 50.Fn ether_aton
40converts an ASCII string of the same form and to a structure 51converts an
41containing the 6 octets of the address. It returns a pointer to a 52.Tn ASCII
42static structure that is reused for each call. 53string of the same form and to a structure
54containing the 6 octets of the address.
55It returns a pointer to a static structure that is reused for each call.
43.Pp 56.Pp
44The 57The
45.Fn ether_ntohost 58.Fn ether_ntohost
46and 59and
47.Fn ether_hostton 60.Fn ether_hostton
48functions interrogate the data base mapping host names to Ethernet 61functions interrogate the database mapping host names to Ethernet
49addresses, 62addresses,
50.Pa /etc/ethers . 63.Pa /etc/ethers .
51The 64The
52.Fn ether_ntohost 65.Fn ether_ntohost
53function looks up the given Ethernet address and writes the associated 66function looks up the given Ethernet address and writes the associated
54host name into the character buffer passed. 67host name into the character buffer passed.
68This buffer should be
69.Dv MAXHOSTNAMELEN
70characters in size.
55The 71The
56.Fn ether_hostton 72.Fn ether_hostton
57function looks up the given host name and writes the associated 73function looks up the given host name and writes the associated
58Ethernet address into the structure passed. Both functions return 74Ethernet address into the structure passed.
59zero if they find the requested host name or address, and -1 if not. 75Both functions return
76zero if they find the requested host name or address, and \-1 if not.
77.Pp
60Each call reads 78Each call reads
61.Pa /etc/ethers 79.Pa /etc/ethers
62from the beginning; if a + appears alone on a line in the file, then 80from the beginning; if a
81.Ql +
82appears alone on a line in the file, then
63.Fn ether_hostton 83.Fn ether_hostton
64will consult the 84will consult the
65.Pa ethers.byname 85.Pa ethers.byname
@@ -73,9 +93,13 @@ The
73.Fn ether_line 93.Fn ether_line
74function parses a line from the 94function parses a line from the
75.Pa /etc/ethers 95.Pa /etc/ethers
76file and fills in the passed ``struct ether_addr'' and character 96file and fills in the passed
77buffer with the Ethernet address and host name on the line. It 97.Li struct ether_addr
78returns zero if the line was successfully parsed and -1 if not. 98and character buffer with the Ethernet address and host name on the line.
99It returns zero if the line was successfully parsed and \-1 if not.
100The character buffer should be
101.Dv MAXHOSTNAMELEN
102characters in size.
79.Sh FILES 103.Sh FILES
80.Bl -tag -width /etc/ethers -compact 104.Bl -tag -width /etc/ethers -compact
81.It Pa /etc/ethers 105.It Pa /etc/ethers
@@ -91,12 +115,8 @@ The
91and 115and
92.Fn ether_line 116.Fn ether_line
93functions were adopted from SunOS and appeared in 117functions were adopted from SunOS and appeared in
94NetBSD 0.9b. 118.Nx 0.9 b.
95.Sh BUGS 119.Sh BUGS
96The data space used by these functions is static; if future use 120The data space used by these functions is static; if future use
97requires the data, it should be copied before any subsequent calls to 121requires the data, it should be copied before any subsequent calls to
98these functions overwrite it. There is no way to restrict how many 122these functions overwrite it.
99character will be written into the host name buffer passed. A very
100long line in
101.Pa /etc/ethers
102could overflow your buffer.
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
index 0f32b9b71b..d4243ff1da 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.20 2005/08/06 20:30:03 espie 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,77 @@
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
45static char * _ether_aton(const char *, struct ether_addr *);
46
26char * 47char *
27ether_ntoa(e) 48ether_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
60static 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(*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 == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
76 return (NULL);
77 e->ether_addr_octet[i] = (u_char)l;
78 s = pp + 1;
79 }
80
81 /* return character after the octets ala strtol(3) */
82 return (pp);
37} 83}
38 84
39struct ether_addr * 85struct ether_addr *
40ether_aton(s) 86ether_aton(const char *s)
41 char *s;
42{ 87{
43 static struct ether_addr n; 88 static struct ether_addr n;
44 u_int i[6]; 89
45 90 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} 91}
58 92
59ether_ntohost(hostname, e) 93int
60 char *hostname; 94ether_ntohost(char *hostname, struct ether_addr *e)
61 struct ether_addr *e;
62{ 95{
63 FILE *f; 96 FILE *f;
64 char buf[BUFSIZ]; 97 char buf[BUFSIZ+1], *p;
98 size_t len;
65 struct ether_addr try; 99 struct ether_addr try;
66
67#ifdef YP 100#ifdef YP
68 char trybuf[sizeof "xx:xx:xx:xx:xx:xx"]; 101 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
69 int trylen; 102 int trylen;
103#endif
70 104
71 sprintf(trybuf, "%x:%x:%x:%x:%x:%x", 105#ifdef YP
106 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
72 e->ether_addr_octet[0], e->ether_addr_octet[1], 107 e->ether_addr_octet[0], e->ether_addr_octet[1],
73 e->ether_addr_octet[2], e->ether_addr_octet[3], 108 e->ether_addr_octet[2], e->ether_addr_octet[3],
74 e->ether_addr_octet[4], e->ether_addr_octet[5]); 109 e->ether_addr_octet[4], e->ether_addr_octet[5]);
@@ -76,12 +111,19 @@ ether_ntohost(hostname, e)
76#endif 111#endif
77 112
78 f = fopen(_PATH_ETHERS, "r"); 113 f = fopen(_PATH_ETHERS, "r");
79 if (f==NULL) 114 if (f == NULL)
80 return -1; 115 return (-1);
81 while (fgets(buf, sizeof buf, f)) { 116 while ((p = fgetln(f, &len)) != NULL) {
117 if (p[len-1] == '\n')
118 len--;
119 if (len > sizeof(buf) - 2)
120 continue;
121 (void)memcpy(buf, p, len);
122 buf[len] = '\n'; /* code assumes newlines later on */
123 buf[len+1] = '\0';
82#ifdef YP 124#ifdef YP
83 /* A + in the file means try YP now. */ 125 /* A + in the file means try YP now. */
84 if (!strncmp(buf, "+\n", sizeof buf)) { 126 if (!strncmp(buf, "+\n", sizeof(buf))) {
85 char *ypbuf, *ypdom; 127 char *ypbuf, *ypdom;
86 int ypbuflen; 128 int ypbuflen;
87 129
@@ -93,42 +135,49 @@ ether_ntohost(hostname, e)
93 if (ether_line(ypbuf, &try, hostname) == 0) { 135 if (ether_line(ypbuf, &try, hostname) == 0) {
94 free(ypbuf); 136 free(ypbuf);
95 (void)fclose(f); 137 (void)fclose(f);
96 return 0; 138 return (0);
97 } 139 }
98 free(ypbuf); 140 free(ypbuf);
99 continue; 141 continue;
100 } 142 }
101#endif 143#endif
102 if (ether_line(buf, &try, hostname) == 0 && 144 if (ether_line(buf, &try, hostname) == 0 &&
103 bcmp((char *)&try, (char *)e, sizeof try) == 0) { 145 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
104 (void)fclose(f); 146 (void)fclose(f);
105 return 0; 147 return (0);
106 } 148 }
107 } 149 }
108 (void)fclose(f); 150 (void)fclose(f);
109 errno = ENOENT; 151 errno = ENOENT;
110 return -1; 152 return (-1);
111} 153}
112 154
113ether_hostton(hostname, e) 155int
114 char *hostname; 156ether_hostton(const char *hostname, struct ether_addr *e)
115 struct ether_addr *e;
116{ 157{
117 FILE *f; 158 FILE *f;
118 char buf[BUFSIZ]; 159 char buf[BUFSIZ+1], *p;
119 char try[MAXHOSTNAMELEN]; 160 char try[MAXHOSTNAMELEN];
161 size_t len;
120#ifdef YP 162#ifdef YP
121 int hostlen = strlen(hostname); 163 int hostlen = strlen(hostname);
122#endif 164#endif
123 165
124 f = fopen(_PATH_ETHERS, "r"); 166 f = fopen(_PATH_ETHERS, "r");
125 if (f==NULL) 167 if (f==NULL)
126 return -1; 168 return (-1);
127 169
128 while (fgets(buf, sizeof buf, f)) { 170 while ((p = fgetln(f, &len)) != NULL) {
171 if (p[len-1] == '\n')
172 len--;
173 if (len > sizeof(buf) - 2)
174 continue;
175 memcpy(buf, p, len);
176 buf[len] = '\n'; /* code assumes newlines later on */
177 buf[len+1] = '\0';
129#ifdef YP 178#ifdef YP
130 /* A + in the file means try YP now. */ 179 /* A + in the file means try YP now. */
131 if (!strncmp(buf, "+\n", sizeof buf)) { 180 if (!strncmp(buf, "+\n", sizeof(buf))) {
132 char *ypbuf, *ypdom; 181 char *ypbuf, *ypdom;
133 int ypbuflen; 182 int ypbuflen;
134 183
@@ -140,7 +189,7 @@ ether_hostton(hostname, e)
140 if (ether_line(ypbuf, e, try) == 0) { 189 if (ether_line(ypbuf, e, try) == 0) {
141 free(ypbuf); 190 free(ypbuf);
142 (void)fclose(f); 191 (void)fclose(f);
143 return 0; 192 return (0);
144 } 193 }
145 free(ypbuf); 194 free(ypbuf);
146 continue; 195 continue;
@@ -148,31 +197,36 @@ ether_hostton(hostname, e)
148#endif 197#endif
149 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) { 198 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
150 (void)fclose(f); 199 (void)fclose(f);
151 return 0; 200 return (0);
152 } 201 }
153 } 202 }
154 (void)fclose(f); 203 (void)fclose(f);
155 errno = ENOENT; 204 errno = ENOENT;
156 return -1; 205 return (-1);
157} 206}
158 207
159ether_line(l, e, hostname) 208int
160 char *l; 209ether_line(const char *line, struct ether_addr *e, char *hostname)
161 struct ether_addr *e;
162 char *hostname;
163{ 210{
164 u_int i[6]; 211 char *p;
165 212 size_t n;
166 if (sscanf(l, " %x:%x:%x:%x:%x:%x %s\n", &i[0], &i[1], 213
167 &i[2], &i[3], &i[4], &i[5], hostname) == 7) { 214 /* Parse "xx:xx:xx:xx:xx:xx" */
168 e->ether_addr_octet[0] = (u_char)i[0]; 215 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
169 e->ether_addr_octet[1] = (u_char)i[1]; 216 goto bad;
170 e->ether_addr_octet[2] = (u_char)i[2]; 217
171 e->ether_addr_octet[3] = (u_char)i[3]; 218 /* Now get the hostname */
172 e->ether_addr_octet[4] = (u_char)i[4]; 219 while (isspace(*p))
173 e->ether_addr_octet[5] = (u_char)i[5]; 220 p++;
174 return 0; 221 if (*p == '\0')
175 } 222 goto bad;
223 n = strcspn(p, " \t\n");
224 if (n >= MAXHOSTNAMELEN)
225 goto bad;
226 strlcpy(hostname, p, n + 1);
227 return (0);
228
229bad:
176 errno = EINVAL; 230 errno = EINVAL;
177 return -1; 231 return (-1);
178} 232}
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";*/
36static char *rcsid = "$Id: calloc.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 35#include <stdlib.h>
40#include <string.h> 36#include <netdb.h>
41 37
42void * 38void
43calloc(num, size) 39freeaddrinfo(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..9a12d9cb57
--- /dev/null
+++ b/src/lib/libc/net/gai_strerror.3
@@ -0,0 +1,93 @@
1.\" $OpenBSD: gai_strerror.3,v 1.6 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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.Fd #include <sys/types.h>
27.Fd #include <sys/socket.h>
28.Fd #include <netdb.h>
29.Ft "const char *"
30.Fn gai_strerror "int ecode"
31.Sh DESCRIPTION
32The
33.Fn gai_strerror
34function returns an error message string corresponding to the error code
35returned by
36.Xr getaddrinfo 3
37or
38.Xr getnameinfo 3 .
39.Pp
40The following error codes and their meaning are defined in
41.Aq Pa netdb.h :
42.Pp
43.Bl -tag -width "EAI_ADDRFAMILYXX" -offset indent -compact
44.It Dv EAI_ADDRFAMILY
45address family for
46.Fa hostname
47not supported
48.It Dv EAI_AGAIN
49temporary failure in name resolution
50.It Dv EAI_BADFLAGS
51invalid value for
52.Fa ai_flags
53.It Dv EAI_BADHINTS
54invalid value for
55.Fa hints
56.It Dv EAI_FAIL
57non-recoverable failure in name resolution
58.It Dv EAI_FAMILY
59.Fa ai_family
60not supported.
61.It Dv EAI_MEMORY
62memory allocation failure
63.It Dv EAI_NODATA
64no address associated with
65.Fa hostname
66.It Dv EAI_NONAME
67.Fa hostname
68or
69.Fa servname
70not provided, or not known
71.It Dv EAI_PROTOCOL
72resolved protocol is unknown
73.It Dv EAI_SERVICE
74.Fa servname
75not supported for
76.Fa ai_socktype
77.It Dv EAI_SOCKTYPE
78.Fa ai_socktype
79not supported
80.It Dv EAI_SYSTEM
81system error returned in
82.Va errno
83.El
84.Sh RETURN VALUES
85.Fn gai_strerror
86returns a pointer to the error message string corresponding to
87.Fa ecode .
88If
89.Fa ecode
90is out of range, an implementation-specific error message string is returned.
91.Sh SEE ALSO
92.Xr getaddrinfo 3 ,
93.Xr getnameinfo 3
diff --git a/src/lib/libc/string/__strsignal.c b/src/lib/libc/net/gai_strerror.c
index 1937e2d608..767bc2f7e8 100644
--- a/src/lib/libc/string/__strsignal.c
+++ b/src/lib/libc/net/gai_strerror.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: gai_strerror.c,v 1.6 2004/12/20 22:35:32 millert Exp $ */
2
1/* 3/*
2 * Copyright (c) 1988 Regents of the University of California. 4 * Copyright (c) 1997-1999, Craig Metz, All rights reserved.
3 * 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,56 +32,45 @@
31 * SUCH DAMAGE. 32 * SUCH DAMAGE.
32 */ 33 */
33 34
34#if defined(LIBC_SCCS) && !defined(lint) 35/* gai_strerror() v1.38 */
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/
36static char *rcsid = "$Id: __strsignal.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#ifdef NLS
40#define catclose _catclose
41#define catgets _catgets
42#define catopen _catopen
43#include <nl_types.h>
44#endif
45 36
46#define sys_siglist _sys_siglist 37#include <sys/types.h>
38#include <netdb.h>
39#include <errno.h>
47 40
48#include <stdio.h> 41const char *
49#include <signal.h> 42gai_strerror(int errnum)
50#include <string.h>
51
52char *
53__strsignal(num, buf)
54 int num;
55 char *buf;
56{ 43{
57#define UPREFIX "Unknown signal: %u" 44 switch (errnum) {
58 register unsigned int signum; 45 case 0:
59 46 return "no error";
60#ifdef NLS 47 case EAI_BADFLAGS:
61 nl_catd catd ; 48 return "invalid value for ai_flags";
62 catd = catopen("libc", 0); 49 case EAI_NONAME:
63#endif 50 return "name or service is not known";
64 51 case EAI_AGAIN:
65 signum = num; /* convert to unsigned */ 52 return "temporary failure in name resolution";
66 if (signum < NSIG) { 53 case EAI_FAIL:
67#ifdef NLS 54 return "non-recoverable failure in name resolution";
68 strcpy(buf, catgets(catd, 2, signum, 55 case EAI_NODATA:
69 (char *)sys_siglist[signum])); 56 return "no address associated with name";
70#else 57 case EAI_FAMILY:
71 return((char *)sys_siglist[signum]); 58 return "ai_family not supported";
72#endif 59 case EAI_SOCKTYPE:
73 } else { 60 return "ai_socktype not supported";
74#ifdef NLS 61 case EAI_SERVICE:
75 sprintf(buf, catgets(catd, 1, 0xffff, UPREFIX), signum); 62 return "service not supported for ai_socktype";
76#else 63 case EAI_ADDRFAMILY:
77 sprintf(buf, UPREFIX, signum); 64 return "address family for name not supported";
78#endif 65 case EAI_MEMORY:
66 return "memory allocation failure";
67 case EAI_SYSTEM:
68 return "system error";
69 case EAI_BADHINTS:
70 return "invalid value for hints";
71 case EAI_PROTOCOL:
72 return "resolved protocol is unknown";
73 default:
74 return "unknown/invalid error";
79 } 75 }
80
81#ifdef NLS
82 catclose(catd);
83#endif
84
85 return buf;
86} 76}
diff --git a/src/lib/libc/net/getaddrinfo.3 b/src/lib/libc/net/getaddrinfo.3
new file mode 100644
index 0000000000..ba42a8e8bd
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.3
@@ -0,0 +1,437 @@
1.\" $OpenBSD: getaddrinfo.3,v 1.45 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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.Fd #include <sys/types.h>
28.Fd #include <sys/socket.h>
29.Fd #include <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
36The
37.Fn getaddrinfo
38function is used to get a list of
39.Tn IP
40addresses and port numbers for host
41.Fa hostname
42and service
43.Fa servname .
44It is a replacement for and provides more flexibility than the
45.Xr gethostbyname 3
46and
47.Xr getservbyname 3
48functions.
49.Pp
50The
51.Fa hostname
52and
53.Fa servname
54arguments are either pointers to NUL-terminated strings or the null pointer.
55An acceptable value for
56.Fa hostname
57is either a valid host name or a numeric host address string consisting
58of a dotted decimal IPv4 address or an IPv6 address.
59The
60.Fa servname
61is either a decimal port number or a service name listed in
62.Xr services 5 .
63At least one of
64.Fa hostname
65and
66.Fa servname
67must be non-null.
68.Pp
69.Fa hints
70is an optional pointer to a
71.Li struct addrinfo ,
72as defined by
73.Aq Pa netdb.h :
74.Bd -literal
75struct 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
87This structure can be used to provide hints concerning the type of socket
88that the caller supports or wishes to use.
89The caller can supply the following structure elements in
90.Fa hints :
91.Bl -tag -width "ai_socktypeXX"
92.It Fa ai_family
93The protocol family that should be used.
94When
95.Fa ai_family
96is set to
97.Dv PF_UNSPEC ,
98it means the caller will accept any protocol family supported by the
99operating system.
100.It Fa ai_socktype
101Denotes the type of socket that is wanted:
102.Dv SOCK_STREAM ,
103.Dv SOCK_DGRAM ,
104or
105.Dv SOCK_RAW .
106When
107.Fa ai_socktype
108is zero the caller will accept any socket type.
109.It Fa ai_protocol
110Indicates which transport protocol is desired,
111.Dv IPPROTO_UDP
112or
113.Dv IPPROTO_TCP .
114If
115.Fa ai_protocol
116is zero the caller will accept any protocol.
117.It Fa ai_flags
118.Fa ai_flags
119is formed by
120.Tn OR Ns 'ing
121the following values:
122.Bl -tag -width "AI_CANONNAMEXX"
123.It Dv AI_CANONNAME
124If the
125.Dv AI_CANONNAME
126bit is set, a successful call to
127.Fn getaddrinfo
128will return a NUL-terminated string containing the canonical name
129of the specified hostname in the
130.Fa ai_canonname
131element of the first
132.Li addrinfo
133structure returned.
134.It Dv AI_NUMERICHOST
135If the
136.Dv AI_NUMERICHOST
137bit is set, it indicates that
138.Fa hostname
139should be treated as a numeric string defining an IPv4 or IPv6 address
140and no name resolution should be attempted.
141.It Dv AI_PASSIVE
142If the
143.Dv AI_PASSIVE
144bit is set it indicates that the returned socket address structure
145is intended for use in a call to
146.Xr bind 2 .
147In this case, if the
148.Fa hostname
149argument is the null pointer, then the IP address portion of the
150socket address structure will be set to
151.Dv INADDR_ANY
152for an IPv4 address or
153.Dv IN6ADDR_ANY_INIT
154for an IPv6 address.
155.Pp
156If the
157.Dv AI_PASSIVE
158bit is not set, the returned socket address structure will be ready
159for use in a call to
160.Xr connect 2
161for a connection-oriented protocol or
162.Xr connect 2 ,
163.Xr sendto 2 ,
164or
165.Xr sendmsg 2
166if a connectionless protocol was chosen.
167The
168.Tn IP
169address portion of the socket address structure will be set to the
170loopback address if
171.Fa hostname
172is the null pointer and
173.Dv AI_PASSIVE
174is not set.
175.El
176.El
177.Pp
178All other elements of the
179.Li addrinfo
180structure passed via
181.Fa hints
182must be zero or the null pointer.
183.Pp
184If
185.Fa hints
186is the null pointer,
187.Fn getaddrinfo
188behaves as if the caller provided a
189.Li struct addrinfo
190with
191.Fa ai_family
192set to
193.Dv PF_UNSPEC
194and all other elements set to zero or
195.Dv NULL .
196.Pp
197After a successful call to
198.Fn getaddrinfo ,
199.Fa *res
200is a pointer to a linked list of one or more
201.Li addrinfo
202structures.
203The list can be traversed by following the
204.Fa ai_next
205pointer in each
206.Li addrinfo
207structure until a null pointer is encountered.
208The three members
209.Fa ai_family ,
210.Fa ai_socktype ,
211and
212.Fa ai_protocol
213in each returned
214.Li addrinfo
215structure are suitable for a call to
216.Xr socket 2 .
217For each
218.Li addrinfo
219structure in the list, the
220.Fa ai_addr
221member points to a filled-in socket address structure of length
222.Fa ai_addrlen .
223.Pp
224This implementation of
225.Fn getaddrinfo
226allows numeric IPv6 address notation with scope identifier,
227as documented in chapter 11 of draft-ietf-ipv6-scoping-arch-02.txt.
228By appending the percent character and scope identifier to addresses,
229one can fill the
230.Li sin6_scope_id
231field for addresses.
232This would make management of scoped addresses easier
233and allows cut-and-paste input of scoped addresses.
234.Pp
235At this moment the code supports only link-local addresses with the format.
236The scope identifier is hardcoded to the name of the hardware interface
237associated
238with the link
239.Po
240such as
241.Li ne0
242.Pc .
243An example is
244.Dq Li fe80::1%ne0 ,
245which means
246.Do
247.Li fe80::1
248on the link associated with the
249.Li ne0
250interface
251.Dc .
252.Pp
253The current implementation assumes a one-to-one relationship between
254the interface and link, which is not necessarily true from the specification.
255.Pp
256All of the information returned by
257.Fn getaddrinfo
258is dynamically allocated: the
259.Li addrinfo
260structures themselves as well as the socket address structures and
261the canonical host name strings included in the
262.Li addrinfo
263structures.
264.Pp
265Memory allocated for the dynamically allocated structures created by
266a successful call to
267.Fn getaddrinfo
268is released by the
269.Fn freeaddrinfo
270function.
271The
272.Fa ai
273pointer should be a
274.Li addrinfo
275structure created by a call to
276.Fn getaddrinfo .
277.Sh RETURN VALUES
278.Fn getaddrinfo
279returns zero on success or one of the error codes listed in
280.Xr gai_strerror 3
281if an error occurs.
282If an error occurs, no memory is allocated by
283.Fn getaddrinfo ,
284therefore it is not necessary to release the
285.Li addrinfo
286structure(s).
287.Sh EXAMPLES
288The following code tries to connect to
289.Dq Li www.kame.net
290service
291.Dq Li www
292via a stream socket.
293It loops through all the addresses available, regardless of address family.
294If the destination resolves to an IPv4 address, it will use an
295.Dv AF_INET
296socket.
297Similarly, if it resolves to IPv6, an
298.Dv AF_INET6
299socket is used.
300Observe that there is no hardcoded reference to a particular address family.
301The code works even if
302.Fn getaddrinfo
303returns addresses that are not IPv4/v6.
304.Bd -literal -offset indent
305struct addrinfo hints, *res, *res0;
306int error;
307int save_errno;
308int s;
309const char *cause = NULL;
310
311memset(&hints, 0, sizeof(hints));
312hints.ai_family = PF_UNSPEC;
313hints.ai_socktype = SOCK_STREAM;
314error = getaddrinfo("www.kame.net", "www", &hints, &res0);
315if (error)
316 errx(1, "%s", gai_strerror(error));
317s = -1;
318for (res = res0; res; res = res->ai_next) {
319 s = socket(res->ai_family, res->ai_socktype,
320 res->ai_protocol);
321 if (s < 0) {
322 cause = "socket";
323 continue;
324 }
325
326 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
327 cause = "connect";
328 save_errno = errno;
329 close(s);
330 errno = save_errno;
331 s = -1;
332 continue;
333 }
334
335 break; /* okay we got one */
336}
337if (s < 0)
338 err(1, "%s", cause);
339freeaddrinfo(res0);
340.Ed
341.Pp
342The following example tries to open a wildcard listening socket onto service
343.Dq Li www ,
344for all the address families available.
345.Bd -literal -offset indent
346struct addrinfo hints, *res, *res0;
347int error;
348int save_errno;
349int s[MAXSOCK];
350int nsock;
351const char *cause = NULL;
352
353memset(&hints, 0, sizeof(hints));
354hints.ai_family = PF_UNSPEC;
355hints.ai_socktype = SOCK_STREAM;
356hints.ai_flags = AI_PASSIVE;
357error = getaddrinfo(NULL, "www", &hints, &res0);
358if (error)
359 errx(1, "%s", gai_strerror(error));
360nsock = 0;
361for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
362 s[nsock] = socket(res->ai_family, res->ai_socktype,
363 res->ai_protocol);
364 if (s[nsock] < 0) {
365 cause = "socket";
366 continue;
367 }
368
369 if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) {
370 cause = "bind";
371 save_errno = errno;
372 close(s[nsock]);
373 errno = save_errno;
374 continue;
375 }
376 (void) listen(s[nsock], 5);
377
378 nsock++;
379}
380if (nsock == 0)
381 err(1, "%s", cause);
382freeaddrinfo(res0);
383.Ed
384.Sh SEE ALSO
385.Xr bind 2 ,
386.Xr connect 2 ,
387.Xr send 2 ,
388.Xr socket 2 ,
389.Xr gai_strerror 3 ,
390.Xr gethostbyname 3 ,
391.Xr getnameinfo 3 ,
392.Xr getservbyname 3 ,
393.Xr resolver 3 ,
394.Xr hosts 5 ,
395.Xr resolv.conf 5 ,
396.Xr services 5 ,
397.Xr hostname 7 ,
398.Xr named 8
399.Rs
400.%A R. Gilligan
401.%A S. Thomson
402.%A J. Bound
403.%A J. McCann
404.%A W. Stevens
405.%T Basic Socket Interface Extensions for IPv6
406.%R RFC 3493
407.%D February 2003
408.Re
409.Rs
410.%A S. Deering
411.%A B. Haberman
412.%A T. Jinmei
413.%A E. Nordmark
414.%A B. Zill
415.%T "IPv6 Scoped Address Architecture"
416.%R internet draft
417.%N draft-ietf-ipv6-scoping-arch-02.txt
418.%O work in progress material
419.Re
420.Rs
421.%A Craig Metz
422.%T Protocol Independence Using the Sockets API
423.%B "Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference"
424.%D June 2000
425.Re
426.Sh STANDARDS
427The
428.Fn getaddrinfo
429function is defined by the
430.St -p1003.1g-2000
431draft specification and documented in
432.Dv "RFC 3493" ,
433.Dq Basic Socket Interface Extensions for IPv6 .
434.Sh BUGS
435The implementation of
436.Fn getaddrinfo
437is not thread-safe.
diff --git a/src/lib/libc/net/getaddrinfo.c b/src/lib/libc/net/getaddrinfo.c
new file mode 100644
index 0000000000..0f3b6319f4
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.c
@@ -0,0 +1,1748 @@
1/* $OpenBSD: getaddrinfo.c,v 1.67 2007/05/20 03:54:52 ray Exp $ */
2/* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Issues to be discussed:
35 * - Thread safe-ness must be checked.
36 * - Return values. There are nonstandard return values defined and used
37 * in the source code. This is because RFC2553 is silent about which error
38 * code must be returned for which situation.
39 * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2
40 * says to use inet_aton() to convert IPv4 numeric to binary (allows
41 * classful form as a result).
42 * current code - disallow classful form for IPv4 (due to use of inet_pton).
43 * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is
44 * invalid.
45 * current code - SEGV on freeaddrinfo(NULL)
46 * Note:
47 * - We use getipnodebyname() just for thread-safeness. There's no intent
48 * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
49 * getipnodebyname().
50 * - The code filters out AFs that are not supported by the kernel,
51 * when globbing NULL hostname (to loopback, or wildcard). Is it the right
52 * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG
53 * in ai_flags?
54 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
55 * (1) what should we do against numeric hostname (2) what should we do
56 * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready?
57 * non-loopback address configured? global address configured?
58 * - To avoid search order issue, we have a big amount of code duplicate
59 * from gethnamaddr.c and some other places. The issues that there's no
60 * lower layer function to lookup "IPv4 or IPv6" record. Calling
61 * gethostbyname2 from getaddrinfo will end up in wrong search order, as
62 * follows:
63 * - The code makes use of following calls when asked to resolver with
64 * ai_family = PF_UNSPEC:
65 * getipnodebyname(host, AF_INET6);
66 * getipnodebyname(host, AF_INET);
67 * This will result in the following queries if the node is configure to
68 * prefer /etc/hosts than DNS:
69 * lookup /etc/hosts for IPv6 address
70 * lookup DNS for IPv6 address
71 * lookup /etc/hosts for IPv4 address
72 * lookup DNS for IPv4 address
73 * which may not meet people's requirement.
74 * The right thing to happen is to have underlying layer which does
75 * PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
76 * This would result in a bit of code duplicate with _dns_ghbyname() and
77 * friends.
78 */
79
80#ifndef INET6
81#define INET6
82#endif
83
84#include <sys/types.h>
85#include <sys/param.h>
86#include <sys/socket.h>
87#include <net/if.h>
88#include <netinet/in.h>
89#include <arpa/inet.h>
90#include <arpa/nameser.h>
91#include <netdb.h>
92#include <resolv.h>
93#include <string.h>
94#include <stdint.h>
95#include <stdlib.h>
96#include <stddef.h>
97#include <ctype.h>
98#include <unistd.h>
99#include <stdio.h>
100#include <errno.h>
101
102#include <syslog.h>
103#include <stdarg.h>
104
105#ifdef YP
106#include <rpc/rpc.h>
107#include <rpcsvc/yp.h>
108#include <rpcsvc/ypclnt.h>
109#include "ypinternal.h"
110#endif
111
112#include "thread_private.h"
113
114#define SUCCESS 0
115#define ANY 0
116#define YES 1
117#define NO 0
118
119static const char in_addrany[] = { 0, 0, 0, 0 };
120static const char in6_addrany[] = {
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
122};
123static const char in_loopback[] = { 127, 0, 0, 1 };
124static const char in6_loopback[] = {
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
126};
127
128static const struct afd {
129 int a_af;
130 int a_addrlen;
131 int a_socklen;
132 int a_off;
133 const char *a_addrany;
134 const char *a_loopback;
135 int a_scoped;
136} afdl [] = {
137#ifdef INET6
138 {PF_INET6, sizeof(struct in6_addr),
139 sizeof(struct sockaddr_in6),
140 offsetof(struct sockaddr_in6, sin6_addr),
141 in6_addrany, in6_loopback, 1},
142#endif
143 {PF_INET, sizeof(struct in_addr),
144 sizeof(struct sockaddr_in),
145 offsetof(struct sockaddr_in, sin_addr),
146 in_addrany, in_loopback, 0},
147 {0, 0, 0, 0, NULL, NULL, 0},
148};
149
150struct explore {
151 int e_af;
152 int e_socktype;
153 int e_protocol;
154 const char *e_protostr;
155 int e_wild;
156#define WILD_AF(ex) ((ex)->e_wild & 0x01)
157#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
158#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
159};
160
161static const struct explore explore[] = {
162#if 0
163 { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
164#endif
165#ifdef INET6
166 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
167 { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
168 { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
169#endif
170 { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
171 { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
172 { PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
173 { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
174 { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
175 { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
176 { -1, 0, 0, NULL, 0 },
177};
178
179#ifdef INET6
180#define PTON_MAX 16
181#else
182#define PTON_MAX 4
183#endif
184
185#define MAXPACKET (64*1024)
186
187typedef union {
188 HEADER hdr;
189 u_char buf[MAXPACKET];
190} querybuf;
191
192struct res_target {
193 struct res_target *next;
194 const char *name; /* domain name */
195 int qclass, qtype; /* class and type of query */
196 u_char *answer; /* buffer to put answer */
197 int anslen; /* size of answer buffer */
198 int n; /* result length */
199};
200
201static int explore_fqdn(const struct addrinfo *, const char *,
202 const char *, struct addrinfo **);
203static int explore_null(const struct addrinfo *,
204 const char *, struct addrinfo **);
205static int explore_numeric(const struct addrinfo *, const char *,
206 const char *, struct addrinfo **, const char *);
207static int explore_numeric_scope(const struct addrinfo *, const char *,
208 const char *, struct addrinfo **);
209static int get_canonname(const struct addrinfo *,
210 struct addrinfo *, const char *);
211static struct addrinfo *get_ai(const struct addrinfo *,
212 const struct afd *, const char *);
213static int get_portmatch(const struct addrinfo *, const char *);
214static int get_port(struct addrinfo *, const char *, int);
215static const struct afd *find_afd(int);
216#ifdef INET6
217static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
218#endif
219
220static struct addrinfo * _gethtent(const char *, const struct addrinfo *,
221 FILE *);
222static struct addrinfo *_files_getaddrinfo(const char *,
223 const struct addrinfo *);
224
225#ifdef YP
226static struct addrinfo *_yphostent(char *, const struct addrinfo *);
227static struct addrinfo *_yp_getaddrinfo(const char *,
228 const struct addrinfo *);
229#endif
230
231static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
232 const struct addrinfo *);
233static int res_queryN(const char *, struct res_target *);
234static int res_searchN(const char *, struct res_target *);
235static int res_querydomainN(const char *, const char *, struct res_target *);
236static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *);
237
238
239/* XXX macros that make external reference is BAD. */
240
241#define GET_AI(ai, afd, addr) \
242do { \
243 /* external reference: pai, error, and label free */ \
244 (ai) = get_ai(pai, (afd), (addr)); \
245 if ((ai) == NULL) { \
246 error = EAI_MEMORY; \
247 goto free; \
248 } \
249} while (/*CONSTCOND*/0)
250
251#define GET_PORT(ai, serv) \
252do { \
253 /* external reference: error and label free */ \
254 error = get_port((ai), (serv), 0); \
255 if (error != 0) \
256 goto free; \
257} while (/*CONSTCOND*/0)
258
259#define GET_CANONNAME(ai, str) \
260do { \
261 /* external reference: pai, error and label free */ \
262 error = get_canonname(pai, (ai), (str)); \
263 if (error != 0) \
264 goto free; \
265} while (/*CONSTCOND*/0)
266
267#define ERR(err) \
268do { \
269 /* external reference: error, and label bad */ \
270 error = (err); \
271 goto bad; \
272 /*NOTREACHED*/ \
273} while (/*CONSTCOND*/0)
274
275#define MATCH_FAMILY(x, y, w) \
276 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
277#define MATCH(x, y, w) \
278 ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
279
280int
281getaddrinfo(const char *hostname, const char *servname,
282 const struct addrinfo *hints, struct addrinfo **res)
283{
284 struct addrinfo sentinel;
285 struct addrinfo *cur;
286 int error = 0;
287 struct addrinfo ai;
288 struct addrinfo ai0;
289 struct addrinfo *pai;
290 const struct explore *ex;
291
292 memset(&sentinel, 0, sizeof(sentinel));
293 cur = &sentinel;
294 pai = &ai;
295 pai->ai_flags = 0;
296 pai->ai_family = PF_UNSPEC;
297 pai->ai_socktype = ANY;
298 pai->ai_protocol = ANY;
299 pai->ai_addrlen = 0;
300 pai->ai_canonname = NULL;
301 pai->ai_addr = NULL;
302 pai->ai_next = NULL;
303
304 if (hostname == NULL && servname == NULL)
305 return EAI_NONAME;
306 if (hints) {
307 /* error check for hints */
308 if (hints->ai_addrlen || hints->ai_canonname ||
309 hints->ai_addr || hints->ai_next)
310 ERR(EAI_BADHINTS); /* xxx */
311 if (hints->ai_flags & ~AI_MASK)
312 ERR(EAI_BADFLAGS);
313 switch (hints->ai_family) {
314 case PF_UNSPEC:
315 case PF_INET:
316#ifdef INET6
317 case PF_INET6:
318#endif
319 break;
320 default:
321 ERR(EAI_FAMILY);
322 }
323 memcpy(pai, hints, sizeof(*pai));
324
325 /*
326 * if both socktype/protocol are specified, check if they
327 * are meaningful combination.
328 */
329 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
330 for (ex = explore; ex->e_af >= 0; ex++) {
331 if (pai->ai_family != ex->e_af)
332 continue;
333 if (ex->e_socktype == ANY)
334 continue;
335 if (ex->e_protocol == ANY)
336 continue;
337 if (pai->ai_socktype == ex->e_socktype
338 && pai->ai_protocol != ex->e_protocol) {
339 ERR(EAI_BADHINTS);
340 }
341 }
342 }
343 }
344
345 /*
346 * check for special cases. (1) numeric servname is disallowed if
347 * socktype/protocol are left unspecified. (2) servname is disallowed
348 * for raw and other inet{,6} sockets.
349 */
350 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
351#ifdef PF_INET6
352 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
353#endif
354 ) {
355 ai0 = *pai; /* backup *pai */
356
357 if (pai->ai_family == PF_UNSPEC) {
358#ifdef PF_INET6
359 pai->ai_family = PF_INET6;
360#else
361 pai->ai_family = PF_INET;
362#endif
363 }
364 error = get_portmatch(pai, servname);
365 if (error)
366 ERR(error);
367
368 *pai = ai0;
369 }
370
371 ai0 = *pai;
372
373 /* NULL hostname, or numeric hostname */
374 for (ex = explore; ex->e_af >= 0; ex++) {
375 *pai = ai0;
376
377 /* PF_UNSPEC entries are prepared for DNS queries only */
378 if (ex->e_af == PF_UNSPEC)
379 continue;
380
381 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
382 continue;
383 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
384 continue;
385 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
386 continue;
387
388 if (pai->ai_family == PF_UNSPEC)
389 pai->ai_family = ex->e_af;
390 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
391 pai->ai_socktype = ex->e_socktype;
392 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
393 pai->ai_protocol = ex->e_protocol;
394
395 if (hostname == NULL)
396 error = explore_null(pai, servname, &cur->ai_next);
397 else
398 error = explore_numeric_scope(pai, hostname, servname,
399 &cur->ai_next);
400
401 if (error)
402 goto free;
403
404 while (cur && cur->ai_next)
405 cur = cur->ai_next;
406 }
407
408 /*
409 * XXX
410 * If numeric representation of AF1 can be interpreted as FQDN
411 * representation of AF2, we need to think again about the code below.
412 */
413 if (sentinel.ai_next)
414 goto good;
415
416 if (hostname == NULL)
417 ERR(EAI_NODATA);
418 if (pai->ai_flags & AI_NUMERICHOST)
419 ERR(EAI_NONAME);
420
421 /*
422 * hostname as alphabetical name.
423 * we would like to prefer AF_INET6 than AF_INET, so we'll make an
424 * outer loop by AFs.
425 */
426 for (ex = explore; ex->e_af >= 0; ex++) {
427 *pai = ai0;
428
429 /* require exact match for family field */
430 if (pai->ai_family != ex->e_af)
431 continue;
432
433 if (!MATCH(pai->ai_socktype, ex->e_socktype,
434 WILD_SOCKTYPE(ex))) {
435 continue;
436 }
437 if (!MATCH(pai->ai_protocol, ex->e_protocol,
438 WILD_PROTOCOL(ex))) {
439 continue;
440 }
441
442 if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
443 pai->ai_socktype = ex->e_socktype;
444 if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
445 pai->ai_protocol = ex->e_protocol;
446
447 error = explore_fqdn(pai, hostname, servname,
448 &cur->ai_next);
449
450 while (cur && cur->ai_next)
451 cur = cur->ai_next;
452 }
453
454 /* XXX */
455 if (sentinel.ai_next)
456 error = 0;
457
458 if (error == 0) {
459 if (sentinel.ai_next) {
460 good:
461 *res = sentinel.ai_next;
462 return SUCCESS;
463 } else
464 error = EAI_FAIL;
465 }
466 free:
467 bad:
468 if (sentinel.ai_next)
469 freeaddrinfo(sentinel.ai_next);
470 *res = NULL;
471 return error;
472}
473
474/*
475 * FQDN hostname, DNS lookup
476 */
477
478static int
479explore_fqdn(const struct addrinfo *pai, const char *hostname,
480 const char *servname, struct addrinfo **res)
481{
482 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
483 struct addrinfo *result;
484 struct addrinfo *cur;
485 int error = 0;
486 char lookups[MAXDNSLUS];
487 int i;
488 _THREAD_PRIVATE_MUTEX(_explore_mutex);
489
490 result = NULL;
491
492 /*
493 * if the servname does not match socktype/protocol, ignore it.
494 */
495 if (get_portmatch(pai, servname) != 0) {
496 return 0;
497 }
498
499 if (_res_init(0) == -1)
500 strlcpy(lookups, "f", sizeof lookups);
501 else {
502 bcopy(_resp->lookups, lookups, sizeof lookups);
503 if (lookups[0] == '\0')
504 strlcpy(lookups, "bf", sizeof lookups);
505 }
506
507 /*
508 * The yp/dns/files getaddrinfo functions are not thread safe.
509 * Protect them with a mutex.
510 */
511 _THREAD_PRIVATE_MUTEX_LOCK(_explore_mutex);
512 for (i = 0; i < MAXDNSLUS && result == NULL && lookups[i]; i++) {
513 switch (lookups[i]) {
514#ifdef YP
515 case 'y':
516 result = _yp_getaddrinfo(hostname, pai);
517 break;
518#endif
519 case 'b':
520 result = _dns_getaddrinfo(hostname, pai);
521 break;
522 case 'f':
523 result = _files_getaddrinfo(hostname, pai);
524 break;
525 }
526 }
527 _THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
528 if (result) {
529 for (cur = result; cur; cur = cur->ai_next) {
530 GET_PORT(cur, servname);
531 /* canonname should be filled already */
532 }
533 *res = result;
534 return 0;
535 } else {
536 /* translate error code */
537 switch (h_errno) {
538 case NETDB_SUCCESS:
539 error = EAI_FAIL; /*XXX strange */
540 break;
541 case HOST_NOT_FOUND:
542 error = EAI_NODATA;
543 break;
544 case TRY_AGAIN:
545 error = EAI_AGAIN;
546 break;
547 case NO_RECOVERY:
548 error = EAI_FAIL;
549 break;
550 case NO_DATA:
551#if NO_ADDRESS != NO_DATA
552 case NO_ADDRESS:
553#endif
554 error = EAI_NODATA;
555 break;
556 default: /* unknown ones */
557 error = EAI_FAIL;
558 break;
559 }
560 }
561
562free:
563 if (result)
564 freeaddrinfo(result);
565 return error;
566}
567
568/*
569 * hostname == NULL.
570 * passive socket -> anyaddr (0.0.0.0 or ::)
571 * non-passive socket -> localhost (127.0.0.1 or ::1)
572 */
573static int
574explore_null(const struct addrinfo *pai, const char *servname,
575 struct addrinfo **res)
576{
577 int s;
578 const struct afd *afd;
579 struct addrinfo *cur;
580 struct addrinfo sentinel;
581 int error;
582
583 *res = NULL;
584 sentinel.ai_next = NULL;
585 cur = &sentinel;
586
587 /*
588 * filter out AFs that are not supported by the kernel
589 * XXX errno?
590 */
591 s = socket(pai->ai_family, SOCK_DGRAM, 0);
592 if (s < 0) {
593 if (errno != EMFILE)
594 return 0;
595 } else
596 close(s);
597
598 /*
599 * if the servname does not match socktype/protocol, ignore it.
600 */
601 if (get_portmatch(pai, servname) != 0)
602 return 0;
603
604 afd = find_afd(pai->ai_family);
605 if (afd == NULL)
606 return 0;
607
608 if (pai->ai_flags & AI_PASSIVE) {
609 GET_AI(cur->ai_next, afd, afd->a_addrany);
610 /* xxx meaningless?
611 * GET_CANONNAME(cur->ai_next, "anyaddr");
612 */
613 } else {
614 GET_AI(cur->ai_next, afd, afd->a_loopback);
615 /* xxx meaningless?
616 * GET_CANONNAME(cur->ai_next, "localhost");
617 */
618 }
619 GET_PORT(cur->ai_next, servname);
620 cur = cur->ai_next;
621
622 *res = sentinel.ai_next;
623 return 0;
624
625free:
626 if (sentinel.ai_next)
627 freeaddrinfo(sentinel.ai_next);
628 return error;
629}
630
631/*
632 * numeric hostname
633 */
634static int
635explore_numeric(const struct addrinfo *pai, const char *hostname,
636 const char *servname, struct addrinfo **res, const char *canonname)
637{
638 const struct afd *afd;
639 struct addrinfo *cur;
640 struct addrinfo sentinel;
641 int error;
642 char pton[PTON_MAX];
643
644 *res = NULL;
645 sentinel.ai_next = NULL;
646 cur = &sentinel;
647
648 /*
649 * if the servname does not match socktype/protocol, ignore it.
650 */
651 if (get_portmatch(pai, servname) != 0)
652 return 0;
653
654 afd = find_afd(pai->ai_family);
655 if (afd == NULL)
656 return 0;
657
658 switch (afd->a_af) {
659#if 0 /*X/Open spec*/
660 case AF_INET:
661 error = inet_aton(hostname, (struct in_addr *)pton);
662 break;
663#endif
664 default:
665 error = inet_pton(afd->a_af, hostname, pton);
666 break;
667 }
668 if (error == 1) {
669 if (pai->ai_family == afd->a_af ||
670 pai->ai_family == PF_UNSPEC /*?*/) {
671 GET_AI(cur->ai_next, afd, pton);
672 GET_PORT(cur->ai_next, servname);
673 if ((pai->ai_flags & AI_CANONNAME)) {
674 /*
675 * Set the numeric address itself as
676 * the canonical name, based on a
677 * clarification in rfc2553bis-03.
678 */
679 GET_CANONNAME(cur->ai_next, canonname);
680 }
681 while (cur && cur->ai_next)
682 cur = cur->ai_next;
683 } else
684 ERR(EAI_FAMILY); /*xxx*/
685 }
686
687 *res = sentinel.ai_next;
688 return 0;
689
690free:
691bad:
692 if (sentinel.ai_next)
693 freeaddrinfo(sentinel.ai_next);
694 return error;
695}
696
697/*
698 * numeric hostname with scope
699 */
700static int
701explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
702 const char *servname, struct addrinfo **res)
703{
704#if !defined(SCOPE_DELIMITER) || !defined(INET6)
705 return explore_numeric(pai, hostname, servname, res, hostname);
706#else
707 const struct afd *afd;
708 struct addrinfo *cur;
709 int error;
710 char *cp, *hostname2 = NULL, *scope, *addr;
711 struct sockaddr_in6 *sin6;
712
713 /*
714 * if the servname does not match socktype/protocol, ignore it.
715 */
716 if (get_portmatch(pai, servname) != 0)
717 return 0;
718
719 afd = find_afd(pai->ai_family);
720 if (afd == NULL)
721 return 0;
722
723 if (!afd->a_scoped)
724 return explore_numeric(pai, hostname, servname, res, hostname);
725
726 cp = strchr(hostname, SCOPE_DELIMITER);
727 if (cp == NULL)
728 return explore_numeric(pai, hostname, servname, res, hostname);
729
730 /*
731 * Handle special case of <scoped_address><delimiter><scope id>
732 */
733 hostname2 = strdup(hostname);
734 if (hostname2 == NULL)
735 return EAI_MEMORY;
736 /* terminate at the delimiter */
737 hostname2[cp - hostname] = '\0';
738 addr = hostname2;
739 scope = cp + 1;
740
741 error = explore_numeric(pai, addr, servname, res, hostname);
742 if (error == 0) {
743 u_int32_t scopeid;
744
745 for (cur = *res; cur; cur = cur->ai_next) {
746 if (cur->ai_family != AF_INET6)
747 continue;
748 sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
749 if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
750 free(hostname2);
751 return(EAI_NODATA); /* XXX: is return OK? */
752 }
753 sin6->sin6_scope_id = scopeid;
754 }
755 }
756
757 free(hostname2);
758
759 return error;
760#endif
761}
762
763static int
764get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
765{
766 if ((pai->ai_flags & AI_CANONNAME) != 0) {
767 ai->ai_canonname = strdup(str);
768 if (ai->ai_canonname == NULL)
769 return EAI_MEMORY;
770 }
771 return 0;
772}
773
774static struct addrinfo *
775get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
776{
777 char *p;
778 struct addrinfo *ai;
779
780 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
781 + (afd->a_socklen));
782 if (ai == NULL)
783 return NULL;
784
785 memcpy(ai, pai, sizeof(struct addrinfo));
786 ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
787 memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
788 ai->ai_addr->sa_len = afd->a_socklen;
789 ai->ai_addrlen = afd->a_socklen;
790 ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
791 p = (char *)(void *)(ai->ai_addr);
792 memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
793 return ai;
794}
795
796static int
797get_portmatch(const struct addrinfo *ai, const char *servname)
798{
799
800 /* get_port does not touch first argument. when matchonly == 1. */
801 /* LINTED const cast */
802 return get_port((struct addrinfo *)ai, servname, 1);
803}
804
805static int
806get_port(struct addrinfo *ai, const char *servname, int matchonly)
807{
808 const char *errstr, *proto;
809 int port;
810 int allownumeric;
811
812 if (servname == NULL)
813 return 0;
814 switch (ai->ai_family) {
815 case AF_INET:
816#ifdef AF_INET6
817 case AF_INET6:
818#endif
819 break;
820 default:
821 return 0;
822 }
823
824 switch (ai->ai_socktype) {
825 case SOCK_RAW:
826 return EAI_SERVICE;
827 case SOCK_DGRAM:
828 case SOCK_STREAM:
829 allownumeric = 1;
830 break;
831 case ANY:
832 allownumeric = 0;
833 break;
834 default:
835 return EAI_SOCKTYPE;
836 }
837
838 port = (int)strtonum(servname, 0, USHRT_MAX, &errstr);
839 if (!errstr) {
840 if (!allownumeric)
841 return EAI_SERVICE;
842 port = htons(port);
843 } else {
844 struct servent sp;
845 struct servent_data sd;
846
847 if (errno == ERANGE)
848 return EAI_SERVICE;
849 if (ai->ai_flags & AI_NUMERICSERV)
850 return EAI_NONAME;
851
852 switch (ai->ai_socktype) {
853 case SOCK_DGRAM:
854 proto = "udp";
855 break;
856 case SOCK_STREAM:
857 proto = "tcp";
858 break;
859 default:
860 proto = NULL;
861 break;
862 }
863
864 (void)memset(&sd, 0, sizeof(sd));
865 if (getservbyname_r(servname, proto, &sp, &sd) == -1)
866 return EAI_SERVICE;
867 port = sp.s_port;
868 endservent_r(&sd);
869 }
870
871 if (!matchonly) {
872 switch (ai->ai_family) {
873 case AF_INET:
874 ((struct sockaddr_in *)(void *)
875 ai->ai_addr)->sin_port = port;
876 break;
877#ifdef INET6
878 case AF_INET6:
879 ((struct sockaddr_in6 *)(void *)
880 ai->ai_addr)->sin6_port = port;
881 break;
882#endif
883 }
884 }
885
886 return 0;
887}
888
889static const struct afd *
890find_afd(int af)
891{
892 const struct afd *afd;
893
894 if (af == PF_UNSPEC)
895 return NULL;
896 for (afd = afdl; afd->a_af; afd++) {
897 if (afd->a_af == af)
898 return afd;
899 }
900 return NULL;
901}
902
903#ifdef INET6
904/* convert a string to a scope identifier. XXX: IPv6 specific */
905static int
906ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
907{
908 struct in6_addr *a6 = &sin6->sin6_addr;
909 const char *errstr;
910
911 /* empty scopeid portion is invalid */
912 if (*scope == '\0')
913 return -1;
914
915 if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
916 IN6_IS_ADDR_MC_INTFACELOCAL(a6)) {
917 /*
918 * We currently assume a one-to-one mapping between links
919 * and interfaces, so we simply use interface indices for
920 * like-local scopes.
921 */
922 *scopeid = if_nametoindex(scope);
923 if (*scopeid == 0)
924 goto trynumeric;
925 return 0;
926 }
927
928 /* still unclear about literal, allow numeric only - placeholder */
929 if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
930 goto trynumeric;
931 if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
932 goto trynumeric;
933 else
934 goto trynumeric; /* global */
935
936 /* try to convert to a numeric id as a last resort */
937 trynumeric:
938 *scopeid = (u_int32_t)strtonum(scope, 0, UINT32_MAX, &errstr);
939 if (errstr)
940 return (-1);
941 return (0);
942}
943#endif
944
945/* code duplicate with gethnamaddr.c */
946
947static const char AskedForGot[] =
948 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
949
950static struct addrinfo *
951getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
952 const struct addrinfo *pai)
953{
954 struct addrinfo sentinel, *cur;
955 struct addrinfo ai;
956 const struct afd *afd;
957 char *canonname;
958 const HEADER *hp;
959 const u_char *cp;
960 int n;
961 const u_char *eom;
962 char *bp, *ep;
963 int type, class, ancount, qdcount;
964 int haveanswer, had_error;
965 char tbuf[MAXDNAME];
966 int (*name_ok)(const char *);
967 char hostbuf[8*1024];
968
969 memset(&sentinel, 0, sizeof(sentinel));
970 cur = &sentinel;
971
972 canonname = NULL;
973 eom = answer->buf + anslen;
974 switch (qtype) {
975 case T_A:
976 case T_AAAA:
977 case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/
978 name_ok = res_hnok;
979 break;
980 default:
981 return (NULL); /* XXX should be abort() -- but that is illegal */
982 }
983 /*
984 * find first satisfactory answer
985 */
986 hp = &answer->hdr;
987 ancount = ntohs(hp->ancount);
988 qdcount = ntohs(hp->qdcount);
989 bp = hostbuf;
990 ep = hostbuf + sizeof hostbuf;
991 cp = answer->buf + HFIXEDSZ;
992 if (qdcount != 1) {
993 h_errno = NO_RECOVERY;
994 return (NULL);
995 }
996 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
997 if ((n < 0) || !(*name_ok)(bp)) {
998 h_errno = NO_RECOVERY;
999 return (NULL);
1000 }
1001 cp += n + QFIXEDSZ;
1002 if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1003 size_t len;
1004
1005 /* res_send() has already verified that the query name is the
1006 * same as the one we sent; this just gets the expanded name
1007 * (i.e., with the succeeding search-domain tacked on).
1008 */
1009 len = strlen(bp) + 1; /* for the \0 */
1010 if (len >= MAXHOSTNAMELEN) {
1011 h_errno = NO_RECOVERY;
1012 return (NULL);
1013 }
1014 canonname = bp;
1015 bp += len;
1016 /* The qname can be abbreviated, but h_name is now absolute. */
1017 qname = canonname;
1018 }
1019 haveanswer = 0;
1020 had_error = 0;
1021 while (ancount-- > 0 && cp < eom && !had_error) {
1022 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1023 if ((n < 0) || !(*name_ok)(bp)) {
1024 had_error++;
1025 continue;
1026 }
1027 cp += n; /* name */
1028 type = _getshort(cp);
1029 cp += INT16SZ; /* type */
1030 class = _getshort(cp);
1031 cp += INT16SZ + INT32SZ; /* class, TTL */
1032 n = _getshort(cp);
1033 cp += INT16SZ; /* len */
1034 if (class != C_IN) {
1035 /* XXX - debug? syslog? */
1036 cp += n;
1037 continue; /* XXX - had_error++ ? */
1038 }
1039 if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1040 type == T_CNAME) {
1041 size_t len;
1042
1043 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1044 if ((n < 0) || !(*name_ok)(tbuf)) {
1045 had_error++;
1046 continue;
1047 }
1048 cp += n;
1049 /* Get canonical name. */
1050 len = strlen(tbuf) + 1; /* for the \0 */
1051 if (len > ep - bp || len >= MAXHOSTNAMELEN) {
1052 had_error++;
1053 continue;
1054 }
1055 strlcpy(bp, tbuf, ep - bp);
1056 canonname = bp;
1057 bp += len;
1058 continue;
1059 }
1060 if (qtype == T_ANY) {
1061 if (!(type == T_A || type == T_AAAA)) {
1062 cp += n;
1063 continue;
1064 }
1065 } else if (type != qtype) {
1066 if (type != T_KEY && type != T_SIG) {
1067 struct syslog_data sdata = SYSLOG_DATA_INIT;
1068
1069 syslog_r(LOG_NOTICE|LOG_AUTH, &sdata,
1070 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1071 qname, p_class(C_IN), p_type(qtype),
1072 p_type(type));
1073 }
1074 cp += n;
1075 continue; /* XXX - had_error++ ? */
1076 }
1077 switch (type) {
1078 case T_A:
1079 case T_AAAA:
1080 if (strcasecmp(canonname, bp) != 0) {
1081 struct syslog_data sdata = SYSLOG_DATA_INIT;
1082
1083 syslog_r(LOG_NOTICE|LOG_AUTH, &sdata,
1084 AskedForGot, canonname, bp);
1085 cp += n;
1086 continue; /* XXX - had_error++ ? */
1087 }
1088 if (type == T_A && n != INADDRSZ) {
1089 cp += n;
1090 continue;
1091 }
1092 if (type == T_AAAA && n != IN6ADDRSZ) {
1093 cp += n;
1094 continue;
1095 }
1096 if (type == T_AAAA) {
1097 struct in6_addr in6;
1098 memcpy(&in6, cp, IN6ADDRSZ);
1099 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1100 cp += n;
1101 continue;
1102 }
1103 }
1104 if (!haveanswer) {
1105 canonname = bp;
1106 bp += strlen(bp) + 1; /* for the \0 */
1107 }
1108
1109 /* don't overwrite pai */
1110 ai = *pai;
1111 ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1112 afd = find_afd(ai.ai_family);
1113 if (afd == NULL) {
1114 cp += n;
1115 continue;
1116 }
1117 cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1118 if (cur->ai_next == NULL)
1119 had_error++;
1120 while (cur && cur->ai_next)
1121 cur = cur->ai_next;
1122 cp += n;
1123 break;
1124 default:
1125 abort(); /* XXX abort illegal in library */
1126 }
1127 if (!had_error)
1128 haveanswer++;
1129 }
1130 if (haveanswer) {
1131 if (!canonname)
1132 (void)get_canonname(pai, sentinel.ai_next, qname);
1133 else
1134 (void)get_canonname(pai, sentinel.ai_next, canonname);
1135 h_errno = NETDB_SUCCESS;
1136 return sentinel.ai_next;
1137 }
1138
1139 h_errno = NO_RECOVERY;
1140 return NULL;
1141}
1142
1143/*ARGSUSED*/
1144static struct addrinfo *
1145_dns_getaddrinfo(const char *name, const struct addrinfo *pai)
1146{
1147 struct addrinfo *ai;
1148 querybuf *buf, *buf2;
1149 struct addrinfo sentinel, *cur;
1150 struct res_target q, q2;
1151
1152 memset(&q, 0, sizeof(q));
1153 memset(&q2, 0, sizeof(q2));
1154 memset(&sentinel, 0, sizeof(sentinel));
1155 cur = &sentinel;
1156
1157 buf = malloc(sizeof(*buf));
1158 if (buf == NULL) {
1159 h_errno = NETDB_INTERNAL;
1160 return NULL;
1161 }
1162 buf2 = malloc(sizeof(*buf2));
1163 if (buf2 == NULL) {
1164 free(buf);
1165 h_errno = NETDB_INTERNAL;
1166 return NULL;
1167 }
1168
1169 switch (pai->ai_family) {
1170 case AF_UNSPEC:
1171 /* prefer IPv6 */
1172 q.qclass = C_IN;
1173 q.qtype = T_AAAA;
1174 q.answer = buf->buf;
1175 q.anslen = sizeof(buf->buf);
1176 q.next = &q2;
1177 q2.qclass = C_IN;
1178 q2.qtype = T_A;
1179 q2.answer = buf2->buf;
1180 q2.anslen = sizeof(buf2->buf);
1181 break;
1182 case AF_INET:
1183 q.qclass = C_IN;
1184 q.qtype = T_A;
1185 q.answer = buf->buf;
1186 q.anslen = sizeof(buf->buf);
1187 break;
1188 case AF_INET6:
1189 q.qclass = C_IN;
1190 q.qtype = T_AAAA;
1191 q.answer = buf->buf;
1192 q.anslen = sizeof(buf->buf);
1193 break;
1194 default:
1195 free(buf);
1196 free(buf2);
1197 return NULL;
1198 }
1199 if (res_searchN(name, &q) < 0) {
1200 free(buf);
1201 free(buf2);
1202 return NULL;
1203 }
1204 ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1205 if (ai) {
1206 cur->ai_next = ai;
1207 while (cur && cur->ai_next)
1208 cur = cur->ai_next;
1209 }
1210 if (q.next) {
1211 ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1212 if (ai)
1213 cur->ai_next = ai;
1214 }
1215 free(buf);
1216 free(buf2);
1217 return sentinel.ai_next;
1218}
1219
1220static struct addrinfo *
1221_gethtent(const char *name, const struct addrinfo *pai, FILE *hostf)
1222{
1223 char *p;
1224 char *cp, *tname, *cname;
1225 struct addrinfo hints, *res0, *res;
1226 int error;
1227 const char *addr;
1228 char hostbuf[8*1024];
1229
1230 again:
1231 if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
1232 return (NULL);
1233 if (*p == '#')
1234 goto again;
1235 if (!(cp = strpbrk(p, "#\n")))
1236 goto again;
1237 *cp = '\0';
1238 if (!(cp = strpbrk(p, " \t")))
1239 goto again;
1240 *cp++ = '\0';
1241 addr = p;
1242 /* if this is not something we're looking for, skip it. */
1243 cname = NULL;
1244 while (cp && *cp) {
1245 if (*cp == ' ' || *cp == '\t') {
1246 cp++;
1247 continue;
1248 }
1249 if (!cname)
1250 cname = cp;
1251 tname = cp;
1252 if ((cp = strpbrk(cp, " \t")) != NULL)
1253 *cp++ = '\0';
1254 if (strcasecmp(name, tname) == 0)
1255 goto found;
1256 }
1257 goto again;
1258
1259found:
1260 hints = *pai;
1261 hints.ai_flags = AI_NUMERICHOST;
1262 error = getaddrinfo(addr, NULL, &hints, &res0);
1263 if (error)
1264 goto again;
1265 for (res = res0; res; res = res->ai_next) {
1266 /* cover it up */
1267 res->ai_flags = pai->ai_flags;
1268
1269 if (pai->ai_flags & AI_CANONNAME) {
1270 if (get_canonname(pai, res, cname) != 0) {
1271 freeaddrinfo(res0);
1272 goto again;
1273 }
1274 }
1275 }
1276 return res0;
1277}
1278
1279/*ARGSUSED*/
1280static struct addrinfo *
1281_files_getaddrinfo(const char *name, const struct addrinfo *pai)
1282{
1283 struct addrinfo sentinel, *cur;
1284 struct addrinfo *p;
1285 FILE *hostf;
1286
1287 hostf = fopen(_PATH_HOSTS, "r");
1288 if (hostf == NULL)
1289 return NULL;
1290
1291 memset(&sentinel, 0, sizeof(sentinel));
1292 cur = &sentinel;
1293
1294 while ((p = _gethtent(name, pai, hostf)) != NULL) {
1295 cur->ai_next = p;
1296 while (cur && cur->ai_next)
1297 cur = cur->ai_next;
1298 }
1299 fclose(hostf);
1300
1301 return sentinel.ai_next;
1302}
1303
1304#ifdef YP
1305static char *__ypdomain;
1306
1307/*ARGSUSED*/
1308static struct addrinfo *
1309_yphostent(char *line, const struct addrinfo *pai)
1310{
1311 struct addrinfo sentinel, *cur;
1312 struct addrinfo hints, *res, *res0;
1313 int error;
1314 char *p = line;
1315 const char *addr, *canonname;
1316 char *nextline;
1317 char *cp;
1318
1319 addr = canonname = NULL;
1320
1321 memset(&sentinel, 0, sizeof(sentinel));
1322 cur = &sentinel;
1323
1324nextline:
1325 /* terminate line */
1326 cp = strchr(p, '\n');
1327 if (cp) {
1328 *cp++ = '\0';
1329 nextline = cp;
1330 } else
1331 nextline = NULL;
1332
1333 cp = strpbrk(p, " \t");
1334 if (cp == NULL) {
1335 if (canonname == NULL)
1336 return (NULL);
1337 else
1338 goto done;
1339 }
1340 *cp++ = '\0';
1341
1342 addr = p;
1343
1344 while (cp && *cp) {
1345 if (*cp == ' ' || *cp == '\t') {
1346 cp++;
1347 continue;
1348 }
1349 if (!canonname)
1350 canonname = cp;
1351 if ((cp = strpbrk(cp, " \t")) != NULL)
1352 *cp++ = '\0';
1353 }
1354
1355 hints = *pai;
1356 hints.ai_flags = AI_NUMERICHOST;
1357 error = getaddrinfo(addr, NULL, &hints, &res0);
1358 if (error == 0) {
1359 for (res = res0; res; res = res->ai_next) {
1360 /* cover it up */
1361 res->ai_flags = pai->ai_flags;
1362
1363 if (pai->ai_flags & AI_CANONNAME)
1364 (void)get_canonname(pai, res, canonname);
1365 }
1366 } else
1367 res0 = NULL;
1368 if (res0) {
1369 cur->ai_next = res0;
1370 while (cur && cur->ai_next)
1371 cur = cur->ai_next;
1372 }
1373
1374 if (nextline) {
1375 p = nextline;
1376 goto nextline;
1377 }
1378
1379done:
1380 return sentinel.ai_next;
1381}
1382
1383/*ARGSUSED*/
1384static struct addrinfo *
1385_yp_getaddrinfo(const char *name, const struct addrinfo *pai)
1386{
1387 struct addrinfo sentinel, *cur;
1388 struct addrinfo *ai = NULL;
1389 static char *__ypcurrent;
1390 int __ypcurrentlen, r;
1391
1392 memset(&sentinel, 0, sizeof(sentinel));
1393 cur = &sentinel;
1394
1395 if (!__ypdomain) {
1396 if (_yp_check(&__ypdomain) == 0)
1397 return NULL;
1398 }
1399 if (__ypcurrent)
1400 free(__ypcurrent);
1401 __ypcurrent = NULL;
1402
1403 /* hosts.byname is only for IPv4 (Solaris8) */
1404 if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
1405 r = yp_match(__ypdomain, "hosts.byname", name,
1406 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1407 if (r == 0) {
1408 struct addrinfo ai4;
1409
1410 ai4 = *pai;
1411 ai4.ai_family = AF_INET;
1412 ai = _yphostent(__ypcurrent, &ai4);
1413 if (ai) {
1414 cur->ai_next = ai;
1415 while (cur && cur->ai_next)
1416 cur = cur->ai_next;
1417 }
1418 }
1419 }
1420
1421 /* ipnodes.byname can hold both IPv4/v6 */
1422 r = yp_match(__ypdomain, "ipnodes.byname", name,
1423 (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
1424 if (r == 0) {
1425 ai = _yphostent(__ypcurrent, pai);
1426 if (ai) {
1427 cur->ai_next = ai;
1428 while (cur && cur->ai_next)
1429 cur = cur->ai_next;
1430 }
1431 }
1432
1433 return sentinel.ai_next;
1434}
1435#endif
1436
1437
1438/* resolver logic */
1439
1440extern const char *__hostalias(const char *);
1441extern int h_errno;
1442extern int res_opt(int, u_char *, int, int);
1443
1444/*
1445 * Formulate a normal query, send, and await answer.
1446 * Returned answer is placed in supplied buffer "answer".
1447 * Perform preliminary check of answer, returning success only
1448 * if no error is indicated and the answer count is nonzero.
1449 * Return the size of the response on success, -1 on error.
1450 * Error number is left in h_errno.
1451 *
1452 * Caller must parse answer and determine whether it answers the question.
1453 */
1454static int
1455res_queryN(const char *name, struct res_target *target)
1456{
1457 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1458 u_char *buf;
1459 HEADER *hp;
1460 int n;
1461 struct res_target *t;
1462 int rcode;
1463 int ancount;
1464
1465 buf = malloc(MAXPACKET);
1466 if (buf == NULL) {
1467 h_errno = NETDB_INTERNAL;
1468 return (-1);
1469 }
1470
1471 rcode = NOERROR;
1472 ancount = 0;
1473
1474 if (_res_init(0) == -1) {
1475 h_errno = NETDB_INTERNAL;
1476 free(buf);
1477 return (-1);
1478 }
1479
1480 for (t = target; t; t = t->next) {
1481 int class, type;
1482 u_char *answer;
1483 int anslen;
1484
1485 hp = (HEADER *)(void *)t->answer;
1486 hp->rcode = NOERROR; /* default */
1487
1488 /* make it easier... */
1489 class = t->qclass;
1490 type = t->qtype;
1491 answer = t->answer;
1492 anslen = t->anslen;
1493#ifdef DEBUG
1494 if (_resp->options & RES_DEBUG)
1495 printf(";; res_query(%s, %d, %d)\n", name, class, type);
1496#endif
1497
1498 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
1499 buf, MAXPACKET);
1500 if (n > 0 && (_resp->options & RES_USE_EDNS0) != 0)
1501 n = res_opt(n, buf, MAXPACKET, anslen);
1502 if (n <= 0) {
1503#ifdef DEBUG
1504 if (_resp->options & RES_DEBUG)
1505 printf(";; res_query: mkquery failed\n");
1506#endif
1507 h_errno = NO_RECOVERY;
1508 free(buf);
1509 return (n);
1510 }
1511 n = res_send(buf, n, answer, anslen);
1512#if 0
1513 if (n < 0) {
1514#ifdef DEBUG
1515 if (_resp->options & RES_DEBUG)
1516 printf(";; res_query: send error\n");
1517#endif
1518 h_errno = TRY_AGAIN;
1519 free(buf);
1520 return (n);
1521 }
1522#endif
1523
1524 if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1525 rcode = hp->rcode; /* record most recent error */
1526#ifdef DEBUG
1527 if (_resp->options & RES_DEBUG)
1528 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
1529 ntohs(hp->ancount));
1530#endif
1531 continue;
1532 }
1533
1534 ancount += ntohs(hp->ancount);
1535
1536 t->n = n;
1537 }
1538
1539 if (ancount == 0) {
1540 switch (rcode) {
1541 case NXDOMAIN:
1542 h_errno = HOST_NOT_FOUND;
1543 break;
1544 case SERVFAIL:
1545 h_errno = TRY_AGAIN;
1546 break;
1547 case NOERROR:
1548 h_errno = NO_DATA;
1549 break;
1550 case FORMERR:
1551 case NOTIMP:
1552 case REFUSED:
1553 default:
1554 h_errno = NO_RECOVERY;
1555 break;
1556 }
1557 free(buf);
1558 return (-1);
1559 }
1560 free(buf);
1561 return (ancount);
1562}
1563
1564/*
1565 * Formulate a normal query, send, and retrieve answer in supplied buffer.
1566 * Return the size of the response on success, -1 on error.
1567 * If enabled, implement search rules until answer or unrecoverable failure
1568 * is detected. Error code, if any, is left in h_errno.
1569 */
1570static int
1571res_searchN(const char *name, struct res_target *target)
1572{
1573 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1574 const char *cp, * const *domain;
1575 HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
1576 u_int dots;
1577 int trailing_dot, ret, saved_herrno;
1578 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
1579
1580 if (_res_init(0) == -1) {
1581 h_errno = NETDB_INTERNAL;
1582 return (-1);
1583 }
1584
1585 errno = 0;
1586 h_errno = HOST_NOT_FOUND; /* default, if we never query */
1587 dots = 0;
1588 for (cp = name; *cp; cp++)
1589 dots += (*cp == '.');
1590 trailing_dot = 0;
1591 if (cp > name && *--cp == '.')
1592 trailing_dot++;
1593
1594 /*
1595 * if there aren't any dots, it could be a user-level alias
1596 */
1597 if (!dots && (cp = __hostalias(name)) != NULL)
1598 return (res_queryN(cp, target));
1599
1600 /*
1601 * If there are dots in the name already, let's just give it a try
1602 * 'as is'. The threshold can be set with the "ndots" option.
1603 */
1604 saved_herrno = -1;
1605 if (dots >= _resp->ndots) {
1606 ret = res_querydomainN(name, NULL, target);
1607 if (ret > 0)
1608 return (ret);
1609 saved_herrno = h_errno;
1610 tried_as_is++;
1611 }
1612
1613 /*
1614 * We do at least one level of search if
1615 * - there is no dot and RES_DEFNAME is set, or
1616 * - there is at least one dot, there is no trailing dot,
1617 * and RES_DNSRCH is set.
1618 */
1619 if ((!dots && (_resp->options & RES_DEFNAMES)) ||
1620 (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
1621 int done = 0;
1622
1623 for (domain = (const char * const *)_resp->dnsrch;
1624 *domain && !done;
1625 domain++) {
1626
1627 ret = res_querydomainN(name, *domain, target);
1628 if (ret > 0)
1629 return (ret);
1630
1631 /*
1632 * If no server present, give up.
1633 * If name isn't found in this domain,
1634 * keep trying higher domains in the search list
1635 * (if that's enabled).
1636 * On a NO_DATA error, keep trying, otherwise
1637 * a wildcard entry of another type could keep us
1638 * from finding this entry higher in the domain.
1639 * If we get some other error (negative answer or
1640 * server failure), then stop searching up,
1641 * but try the input name below in case it's
1642 * fully-qualified.
1643 */
1644 if (errno == ECONNREFUSED) {
1645 h_errno = TRY_AGAIN;
1646 return (-1);
1647 }
1648
1649 switch (h_errno) {
1650 case NO_DATA:
1651 got_nodata++;
1652 /* FALLTHROUGH */
1653 case HOST_NOT_FOUND:
1654 /* keep trying */
1655 break;
1656 case TRY_AGAIN:
1657 if (hp->rcode == SERVFAIL) {
1658 /* try next search element, if any */
1659 got_servfail++;
1660 break;
1661 }
1662 /* FALLTHROUGH */
1663 default:
1664 /* anything else implies that we're done */
1665 done++;
1666 }
1667 /*
1668 * if we got here for some reason other than DNSRCH,
1669 * we only wanted one iteration of the loop, so stop.
1670 */
1671 if (!(_resp->options & RES_DNSRCH))
1672 done++;
1673 }
1674 }
1675
1676 /*
1677 * if we have not already tried the name "as is", do that now.
1678 * note that we do this regardless of how many dots were in the
1679 * name or whether it ends with a dot.
1680 */
1681 if (!tried_as_is) {
1682 ret = res_querydomainN(name, NULL, target);
1683 if (ret > 0)
1684 return (ret);
1685 }
1686
1687 /*
1688 * if we got here, we didn't satisfy the search.
1689 * if we did an initial full query, return that query's h_errno
1690 * (note that we wouldn't be here if that query had succeeded).
1691 * else if we ever got a nodata, send that back as the reason.
1692 * else send back meaningless h_errno, that being the one from
1693 * the last DNSRCH we did.
1694 */
1695 if (saved_herrno != -1)
1696 h_errno = saved_herrno;
1697 else if (got_nodata)
1698 h_errno = NO_DATA;
1699 else if (got_servfail)
1700 h_errno = TRY_AGAIN;
1701 return (-1);
1702}
1703
1704/*
1705 * Perform a call on res_query on the concatenation of name and domain,
1706 * removing a trailing dot from name if domain is NULL.
1707 */
1708static int
1709res_querydomainN(const char *name, const char *domain,
1710 struct res_target *target)
1711{
1712 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1713 char nbuf[MAXDNAME];
1714 const char *longname = nbuf;
1715 size_t len;
1716
1717 if (_res_init(0) == -1) {
1718 h_errno = NETDB_INTERNAL;
1719 return (-1);
1720 }
1721#ifdef DEBUG
1722 if (_resp->options & RES_DEBUG)
1723 printf(";; res_querydomain(%s, %s)\n",
1724 name, domain?domain:"<Nil>");
1725#endif
1726 if (domain == NULL) {
1727 /*
1728 * Check for trailing '.';
1729 * copy without '.' if present.
1730 */
1731 len = strlcpy(nbuf, name, sizeof(nbuf));
1732 if (len >= sizeof(nbuf)) {
1733 h_errno = NO_RECOVERY;
1734 return (-1);
1735 }
1736 if (len > 0 && nbuf[len - 1] == '.')
1737 nbuf[len - 1] = '\0';
1738 } else {
1739 int i;
1740
1741 i = snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
1742 if (i < 0 || i >= sizeof(nbuf)) {
1743 h_errno = NO_RECOVERY;
1744 return (-1);
1745 }
1746 }
1747 return (res_queryN(longname, target));
1748}
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
index bac0368296..1a05460da4 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.25 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993 3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,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: May 31 2007 $
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.Fd #include <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
60The 63The
61.Fn gethostbyname 64.Fn gethostbyname ,
65.Fn gethostbyname2 ,
62and 66and
63.Fn gethostbyaddr 67.Fn gethostbyaddr
64functions 68functions each return a pointer to an object with the following structure
65each return a pointer to an object with the 69describing an Internet host referenced by name or by address, respectively.
66following structure describing an internet host 70This structure contains either information obtained from the name server (i.e.,
67referenced by name or by address, respectively. 71.Xr resolver 3
68This structure contains either the information obtained from the name server, 72and
69.Xr named 8 , 73.Xr named 8 ) ,
70broken-out fields from a line in 74broken-out fields from a line in
71.Pa /etc/hosts , 75.Pa /etc/hosts ,
72or database entries supplied by the 76or database entries supplied by the
73.Xr yp 8 77.Xr yp 8
74system . 78system.
75If the local name server is not running these routines do a lookup in 79.Xr resolv.conf 5
76.Pa /etc/hosts . 80describes how the particular database is chosen.
77.Bd -literal 81.Bd -literal -offset indent
78struct hostent { 82struct 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
88The members of this structure are: 92The 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
91Official name of the host. 95Official name of the host.
92.It Fa h_aliases 96.It Fa h_aliases
93A zero terminated array of alternate names for the host. 97A null-terminated array of alternate names for the host.
94.It Fa h_addrtype 98.It Fa h_addrtype
95The type of address being returned; currently always 99The type of address being returned.
96.Dv AF_INET .
97.It Fa h_length 100.It Fa h_length
98The length, in bytes, of the address. 101The length, in bytes, of the address.
99.It Fa h_addr_list 102.It Fa h_addr_list
100A zero terminated array of network addresses for the host. 103A null-terminated array of network addresses for the host.
101Host addresses are returned in network byte order. 104Host addresses are returned in network byte order.
102.It Fa h_addr 105.It Fa h_addr
103The first address in 106The first address in
104.Fa h_addr_list ; 107.Fa h_addr_list ;
105this is for backward compatibility. 108this is for backward compatibility.
109.El
106.Pp 110.Pp
107When using the nameserver, 111The function
108.Fn gethostbyname 112.Fn gethostbyname
109will search for the named host in the current domain and its parents 113will search for the named host in the current domain and its parents
110unless the name ends in a dot. 114using the search lookup semantics detailed in
111If the name contains no dot, and if the environment variable 115.Xr resolv.conf 5
112.Dq Ev HOSTALIASES 116and
113contains the name of an alias file, the alias file will first be searched 117.Xr hostname 7 .
114for an alias matching the input name. 118.Pp
115See 119.Fn gethostbyname2
116.Xr hostname 7 120is an advanced form of
117for the domain search procedure and the alias file format. 121.Fn gethostbyname
122which allows lookups in address families other than
123.Dv AF_INET .
124Currently, the only supported address family besides
125.Dv AF_INET
126is
127.Dv AF_INET6 .
128.Pp
129The
130.Fn gethostbyaddr
131function will search for the specified address of length
132.Fa len
133in the address family
134.Fa af .
135The only address family currently supported is
136.Dv AF_INET .
118.Pp 137.Pp
119The 138The
120.Fn sethostent 139.Fn sethostent
121function 140function may be used to request the use of a connected
122may be used to request the use of a connected
123.Tn TCP 141.Tn TCP
124socket for queries. 142socket for queries.
125If the 143If the
@@ -127,7 +145,7 @@ If the
127flag is non-zero, 145flag is non-zero,
128this sets the option to send all queries to the name server using 146this sets the option to send all queries to the name server using
129.Tn TCP 147.Tn TCP
130and to retain the connection after each call to 148and to retain the connection after each call to
131.Fn gethostbyname 149.Fn gethostbyname
132or 150or
133.Fn gethostbyaddr . 151.Fn gethostbyaddr .
@@ -137,17 +155,46 @@ datagrams.
137.Pp 155.Pp
138The 156The
139.Fn endhostent 157.Fn endhostent
140function 158function closes the
141closes the
142.Tn TCP 159.Tn TCP
143connection. 160connection.
161.Pp
162The
163.Fn herror
164function prints an error message describing the failure.
165If its argument
166.Fa string
167is non-null,
168it is prepended to the message string and separated from it by a colon
169.Pq Ql \&:
170and a space.
171The error message is printed with a trailing newline.
172The contents of the error message is the same as that returned by
173.Fn hstrerror
174with argument
175.Fa h_errno .
176.Sh ENVIRONMENT
177.Bl -tag -width HOSTALIASES
178.It HOSTALIASES
179A file containing local host aliases.
180See
181.Xr hostname 7
182for more information.
183.It RES_OPTIONS
184A list of options to override the resolver's internal defaults.
185See
186.Xr resolver 3
187for more information.
188.El
144.Sh FILES 189.Sh FILES
145.Bl -tag -width /etc/hosts -compact 190.Bl -tag -width /etc/resolv.conf -compact
146.It Pa /etc/hosts 191.It Pa /etc/hosts
192.It Pa /etc/resolv.conf
147.El 193.El
148.Sh DIAGNOSTICS 194.Sh DIAGNOSTICS
149Error return status from 195Error return status from
150.Fn gethostbyname 196.Fn gethostbyname ,
197.Fn gethostbyname2 ,
151and 198and
152.Fn gethostbyaddr 199.Fn gethostbyaddr
153is indicated by return of a null pointer. 200is indicated by return of a null pointer.
@@ -155,15 +202,6 @@ The external integer
155.Va h_errno 202.Va h_errno
156may then be checked to see whether this is a temporary failure 203may then be checked to see whether this is a temporary failure
157or an invalid or unknown host. 204or an invalid or unknown host.
158The routine
159.Fn herror
160can be used to print an error message describing the failure.
161If its argument
162.Fa string
163is
164.Pf non Dv -NULL ,
165it is printed, followed by a colon and a space.
166The error message is printed with a trailing newline.
167.Pp 205.Pp
168The variable 206The variable
169.Va h_errno 207.Va h_errno
@@ -180,75 +218,80 @@ A retry at some later time may succeed.
180Some unexpected server failure was encountered. 218Some unexpected server failure was encountered.
181This is a non-recoverable error. 219This is a non-recoverable error.
182.It Dv NO_DATA 220.It Dv NO_DATA
183The requested name is valid but does not have an IP address; 221The requested name is valid but does not have an IP address;
184this is not a temporary error. 222this is not a temporary error.
185This means that the name is known to the name server but there is no address 223This means that the name is known to the name server but there is no address
186associated with this name. 224associated with this name.
187Another type of request to the name server using this domain name 225Another type of request to the name server using this domain name
188will result in an answer; 226will result in an answer;
189for example, a mail-forwarder may be registered for this domain. 227for example, a mail-forwarder may be registered for this domain.
228.It Dv NETDB_INTERNAL
229An internal error occurred.
230This may occur when an address family other than
231.Dv AF_INET
232or
233.Dv AF_INET6
234is specified or when a resource is unable to be allocated.
235.It Dv NETDB_SUCCESS
236The function completed successfully.
190.El 237.El
191.Sh SEE ALSO 238.Sh SEE ALSO
239.Xr getaddrinfo 3 ,
240.Xr getnameinfo 3 ,
192.Xr resolver 3 , 241.Xr resolver 3 ,
193.Xr hosts 5 , 242.Xr hosts 5 ,
243.Xr resolv.conf 5 ,
194.Xr hostname 7 , 244.Xr hostname 7 ,
195.Xr named 8 245.Xr named 8
196.Sh CAVEAT 246.Sh HISTORY
197The 247The
198.Fn gethostent 248.Fn herror
199function 249function appeared in
200is defined, and 250.Bx 4.3 .
201.Fn sethostent 251The
252.Fn endhostent ,
253.Fn gethostbyaddr ,
254.Fn gethostbyname ,
255.Fn gethostent ,
202and 256and
203.Fn endhostent 257.Fn sethostent
204are redefined, 258functions appeared in
205when 259.Bx 4.2 .
206.Xr libc 3 260.Sh CAVEATS
207is built to use only the routines to lookup in 261If the search routines in
262.Xr resolv.conf 5
263decide to read the
208.Pa /etc/hosts 264.Pa /etc/hosts
209and not the name server. 265file,
210.Pp
211The
212.Fn gethostent 266.Fn gethostent
213function 267and other functions will
214reads the next line of 268read the next line of the file,
215.Pa /etc/hosts , 269re-opening the file if necessary.
216opening the file if necessary.
217.Pp 270.Pp
218The 271The
219.Fn sethostent 272.Fn sethostent
220function 273function opens and/or rewinds the file
221opens and/or rewinds the file
222.Pa /etc/hosts . 274.Pa /etc/hosts .
223If the 275If the
224.Fa stayopen 276.Fa stayopen
225argument is non-zero, 277argument is non-zero, the file will not be closed after each call to
226the file will not be closed after each call to 278.Fn gethostbyname ,
227.Fn gethostbyname 279.Fn gethostbyname2 ,
228or 280or
229.Fn gethostbyaddr . 281.Fn gethostbyaddr .
230.Pp 282.Pp
231The 283The
232.Fn endhostent 284.Fn endhostent
233function 285function closes the file.
234closes the file.
235.Sh HISTORY
236The
237.Fn herror
238function appeared in
239.Bx 4.3 .
240The
241.Fn endhostent ,
242.Fn gethostbyaddr ,
243.Fn gethostbyname ,
244.Fn gethostent ,
245and
246.Fn sethostent
247functions appeared in
248.Bx 4.2 .
249.Sh BUGS 286.Sh BUGS
250These functions use static data storage; 287These functions use static data storage;
251if the data is needed for future use, it should be 288if the data is needed for future use, it should be
252copied before any subsequent calls overwrite it. 289copied before any subsequent calls overwrite it.
290.Pp
253Only the Internet 291Only the Internet
254address format is currently understood. 292address formats are currently understood.
293.Pp
294YP does not support any address families other than
295.Dv AF_INET
296and uses
297the traditional database format.
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index ec3f14a900..d49b9cdd7d 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -1,5 +1,4 @@
1/* $NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $ */ 1/* $OpenBSD: gethostnamadr.c,v 1.72 2007/10/11 18:36:41 jakob Exp $ */
2
3/*- 2/*-
4 * Copyright (c) 1985, 1988, 1993 3 * Copyright (c) 1985, 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 *
@@ -53,15 +48,6 @@
53 * --Copyright-- 48 * --Copyright--
54 */ 49 */
55 50
56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0
58static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycroft Exp $";
62#endif
63#endif /* LIBC_SCCS and not lint */
64
65#include <sys/param.h> 51#include <sys/param.h>
66#include <sys/socket.h> 52#include <sys/socket.h>
67#include <netinet/in.h> 53#include <netinet/in.h>
@@ -73,11 +59,17 @@ static char rcsid[] = "$NetBSD: gethostnamadr.c,v 1.13 1995/05/21 16:21:14 mycro
73#include <ctype.h> 59#include <ctype.h>
74#include <errno.h> 60#include <errno.h>
75#include <string.h> 61#include <string.h>
62#include <syslog.h>
63#include <stdlib.h>
76#ifdef YP 64#ifdef YP
77#include <rpc/rpc.h> 65#include <rpc/rpc.h>
78#include <rpcsvc/yp_prot.h> 66#include <rpcsvc/yp.h>
79#include <rpcsvc/ypclnt.h> 67#include <rpcsvc/ypclnt.h>
68#include "ypinternal.h"
80#endif 69#endif
70#include "thread_private.h"
71
72#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
81 73
82#define MAXALIASES 35 74#define MAXALIASES 35
83#define MAXADDRS 35 75#define MAXADDRS 35
@@ -91,47 +83,101 @@ static char *__ypdomain;
91static struct hostent host; 83static struct hostent host;
92static char *host_aliases[MAXALIASES]; 84static char *host_aliases[MAXALIASES];
93static char hostbuf[BUFSIZ+1]; 85static char hostbuf[BUFSIZ+1];
94static struct in_addr host_addr; 86static union {
87 struct in_addr _host_in_addr;
88 u_char _host_addr[16]; /* IPv4 or IPv6 */
89} _host_addr_u;
90#define host_addr _host_addr_u._host_addr
95static FILE *hostf = NULL; 91static FILE *hostf = NULL;
96static int stayopen = 0; 92static int stayopen = 0;
97 93
98#if PACKETSZ > 1024 94static void map_v4v6_address(const char *src, char *dst);
99#define MAXPACKET PACKETSZ 95static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
100#else 96
101#define MAXPACKET 1024 97#ifdef RESOLVSORT
98static void addrsort(char **, int);
102#endif 99#endif
103 100
101int _hokchar(const char *);
102
103static const char AskedForGot[] =
104 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
105
106#define MAXPACKET (64*1024)
107
104typedef union { 108typedef union {
105 HEADER hdr; 109 HEADER hdr;
106 u_char buf[MAXPACKET]; 110 u_char buf[MAXPACKET];
107} querybuf; 111} querybuf;
108 112
109typedef union { 113typedef union {
110 int32_t al; 114 int32_t al;
111 char ac; 115 char ac;
112} align; 116} align;
113 117
114static int qcomp __P((struct in_addr **, struct in_addr **)); 118static struct hostent *getanswer(const querybuf *, int, const char *, int);
115static struct hostent *getanswer __P((querybuf *, int, int));
116 119
117extern int h_errno; 120extern int h_errno;
118 121
122int
123_hokchar(const char *p)
124{
125 char c;
126
127 /*
128 * Many people do not obey RFC 822 and 1035. The valid
129 * characters are a-z, A-Z, 0-9, '-' and . But the others
130 * tested for below can happen, and we must be more permissive
131 * than the resolver until those idiots clean up their act.
132 * We let '/' through, but not '..'
133 */
134 while ((c = *p++)) {
135 if (('a' <= c && c <= 'z') ||
136 ('A' <= c && c <= 'Z') ||
137 ('0' <= c && c <= '9'))
138 continue;
139 if (strchr("-_/", c))
140 continue;
141 if (c == '.' && *p != '.')
142 continue;
143 return 0;
144 }
145 return 1;
146}
147
119static struct hostent * 148static struct hostent *
120getanswer(answer, anslen, iquery) 149getanswer(const querybuf *answer, int anslen, const char *qname, int qtype)
121 querybuf *answer;
122 int anslen;
123 int iquery;
124{ 150{
125 register HEADER *hp; 151 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
126 register u_char *cp; 152 const HEADER *hp;
127 register int n; 153 const u_char *cp, *eom;
128 u_char *eom; 154 char tbuf[MAXDNAME];
129 char *bp, **ap; 155 char *bp, **ap, **hap, *ep;
130 int type, class, buflen, ancount, qdcount; 156 int type, class, ancount, qdcount, n;
131 int haveanswer, getclass = C_ANY; 157 int haveanswer, had_error, toobig = 0;
132 char **hap; 158 const char *tname;
159 int (*name_ok)(const char *);
133 160
161 tname = qname;
162 host.h_name = NULL;
134 eom = answer->buf + anslen; 163 eom = answer->buf + anslen;
164 switch (qtype) {
165 case T_A:
166 case T_AAAA:
167#ifdef USE_RESOLV_NAME_OK
168 name_ok = res_hnok;
169 break;
170#endif
171 case T_PTR:
172#ifdef USE_RESOLV_NAME_OK
173 name_ok = res_dnok;
174#else
175 name_ok = _hokchar;
176#endif
177 break;
178 default:
179 return (NULL);
180 }
135 /* 181 /*
136 * find first satisfactory answer 182 * find first satisfactory answer
137 */ 183 */
@@ -139,31 +185,27 @@ getanswer(answer, anslen, iquery)
139 ancount = ntohs(hp->ancount); 185 ancount = ntohs(hp->ancount);
140 qdcount = ntohs(hp->qdcount); 186 qdcount = ntohs(hp->qdcount);
141 bp = hostbuf; 187 bp = hostbuf;
142 buflen = sizeof(hostbuf); 188 ep = hostbuf + sizeof hostbuf;
143 cp = answer->buf + sizeof(HEADER); 189 cp = answer->buf + HFIXEDSZ;
144 if (qdcount) { 190 if (qdcount != 1) {
145 if (iquery) { 191 h_errno = NO_RECOVERY;
146 if ((n = dn_expand((u_char *)answer->buf, 192 return (NULL);
147 (u_char *)eom, (u_char *)cp, (u_char *)bp, 193 }
148 buflen)) < 0) { 194 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
149 h_errno = NO_RECOVERY; 195 if ((n < 0) || !(*name_ok)(bp)) {
150 return ((struct hostent *) NULL); 196 h_errno = NO_RECOVERY;
151 } 197 return (NULL);
152 cp += n + QFIXEDSZ; 198 }
153 host.h_name = bp; 199 cp += n + QFIXEDSZ;
154 n = strlen(bp) + 1; 200 if (qtype == T_A || qtype == T_AAAA) {
155 bp += n; 201 /* res_send() has already verified that the query name is the
156 buflen -= n; 202 * same as the one we sent; this just gets the expanded name
157 } else 203 * (i.e., with the succeeding search-domain tacked on).
158 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 204 */
159 while (--qdcount > 0) 205 host.h_name = bp;
160 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 206 bp += strlen(bp) + 1; /* for the \0 */
161 } else if (iquery) { 207 /* The qname can be abbreviated, but h_name is now absolute. */
162 if (hp->aa) 208 qname = host.h_name;
163 h_errno = HOST_NOT_FOUND;
164 else
165 h_errno = TRY_AGAIN;
166 return ((struct hostent *) NULL);
167 } 209 }
168 ap = host_aliases; 210 ap = host_aliases;
169 *ap = NULL; 211 *ap = NULL;
@@ -172,103 +214,323 @@ getanswer(answer, anslen, iquery)
172 *hap = NULL; 214 *hap = NULL;
173 host.h_addr_list = h_addr_ptrs; 215 host.h_addr_list = h_addr_ptrs;
174 haveanswer = 0; 216 haveanswer = 0;
175 while (--ancount >= 0 && cp < eom) { 217 had_error = 0;
176 if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, 218 while (ancount-- > 0 && cp < eom && !had_error) {
177 (u_char *)cp, (u_char *)bp, buflen)) < 0) 219 size_t len;
220
221 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
222 if ((n < 0) || !(*name_ok)(bp)) {
223 had_error++;
224 continue;
225 }
226 cp += n; /* name */
227 if (cp >= eom)
178 break; 228 break;
179 cp += n;
180 type = _getshort(cp); 229 type = _getshort(cp);
181 cp += sizeof(u_int16_t); 230 cp += INT16SZ; /* type */
231 if (cp >= eom)
232 break;
182 class = _getshort(cp); 233 class = _getshort(cp);
183 cp += sizeof(u_int16_t) + sizeof(u_int32_t); 234 cp += INT16SZ + INT32SZ; /* class, TTL */
235 if (cp >= eom)
236 break;
184 n = _getshort(cp); 237 n = _getshort(cp);
185 cp += sizeof(u_int16_t); 238 cp += INT16SZ; /* len */
186 if (type == T_CNAME) { 239 if (cp >= eom)
240 break;
241 if (type == T_SIG || type == T_RRSIG) {
242 /* XXX - ignore signatures as we don't use them yet */
187 cp += n; 243 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; 244 continue;
195 } 245 }
196 if (iquery && type == T_PTR) { 246 if (class != C_IN) {
197 if ((n = dn_expand((u_char *)answer->buf, 247 /* XXX - debug? syslog? */
198 (u_char *)eom, (u_char *)cp, (u_char *)bp,
199 buflen)) < 0)
200 break;
201 cp += n; 248 cp += n;
249 continue; /* XXX - had_error++ ? */
250 }
251 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
252 if (ap >= &host_aliases[MAXALIASES-1])
253 continue;
254 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
255 if ((n < 0) || !(*name_ok)(tbuf)) {
256 had_error++;
257 continue;
258 }
259 cp += n;
260 /* Store alias. */
261 *ap++ = bp;
262 bp += strlen(bp) + 1; /* for the \0 */
263 /* Get canonical name. */
264 len = strlen(tbuf) + 1; /* for the \0 */
265 if (len > ep - bp) {
266 had_error++;
267 continue;
268 }
269 strlcpy(bp, tbuf, ep - bp);
202 host.h_name = bp; 270 host.h_name = bp;
203 return(&host); 271 bp += len;
272 continue;
204 } 273 }
205 if (iquery || type != T_A) { 274 if (qtype == T_PTR && type == T_CNAME) {
206#ifdef DEBUG 275 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
207 if (_res.options & RES_DEBUG) 276#ifdef USE_RESOLV_NAME_OK
208 printf("unexpected answer type %d, size %d\n", 277 if ((n < 0) || !res_hnok(tbuf)) {
209 type, n); 278#else
279 if ((n < 0) || !_hokchar(tbuf)) {
210#endif 280#endif
281 had_error++;
282 continue;
283 }
211 cp += n; 284 cp += n;
285 /* Get canonical name. */
286 len = strlen(tbuf) + 1; /* for the \0 */
287 if (len > ep - bp) {
288 had_error++;
289 continue;
290 }
291 strlcpy(bp, tbuf, ep - bp);
292 tname = bp;
293 bp += len;
212 continue; 294 continue;
213 } 295 }
214 if (haveanswer) { 296 if (type != qtype) {
215 if (n != host.h_length) { 297 syslog(LOG_NOTICE|LOG_AUTH,
298 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
299 qname, p_class(C_IN), p_type(qtype),
300 p_type(type));
301 cp += n;
302 continue; /* XXX - had_error++ ? */
303 }
304 switch (type) {
305 case T_PTR:
306 if (strcasecmp(tname, bp) != 0) {
307 syslog(LOG_NOTICE|LOG_AUTH,
308 AskedForGot, qname, bp);
216 cp += n; 309 cp += n;
217 continue; 310 continue; /* XXX - had_error++ ? */
311 }
312 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
313#ifdef USE_RESOLV_NAME_OK
314 if ((n < 0) || !res_hnok(bp)) {
315#else
316 if ((n < 0) || !_hokchar(bp)) {
317#endif
318 had_error++;
319 break;
320 }
321#if MULTI_PTRS_ARE_ALIASES
322 cp += n;
323 if (!haveanswer)
324 host.h_name = bp;
325 else if (ap < &host_aliases[MAXALIASES-1])
326 *ap++ = bp;
327 else
328 n = -1;
329 if (n != -1) {
330 n = strlen(bp) + 1; /* for the \0 */
331 bp += n;
332 }
333 break;
334#else
335 host.h_name = bp;
336 if (_resp->options & RES_USE_INET6) {
337 n = strlen(bp) + 1; /* for the \0 */
338 bp += n;
339 map_v4v6_hostent(&host, &bp, ep);
340 }
341 h_errno = NETDB_SUCCESS;
342 return (&host);
343#endif
344 case T_A:
345 case T_AAAA:
346 if (strcasecmp(host.h_name, bp) != 0) {
347 syslog(LOG_NOTICE|LOG_AUTH,
348 AskedForGot, host.h_name, bp);
349 cp += n;
350 continue; /* XXX - had_error++ ? */
218 } 351 }
219 if (class != getclass) { 352 if (n != host.h_length) {
220 cp += n; 353 cp += n;
221 continue; 354 continue;
222 } 355 }
223 } else { 356 if (type == T_AAAA) {
224 host.h_length = n; 357 struct in6_addr in6;
225 getclass = class; 358 memcpy(&in6, cp, IN6ADDRSZ);
226 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; 359 if (IN6_IS_ADDR_V4MAPPED(&in6)) {
227 if (!iquery) { 360 cp += n;
361 continue;
362 }
363 }
364 if (!haveanswer) {
228 host.h_name = bp; 365 host.h_name = bp;
229 bp += strlen(bp) + 1; 366 bp += strlen(bp) + 1; /* for the \0 */
230 } 367 }
231 }
232 368
233 bp += sizeof(align) - ((u_long)bp % sizeof(align)); 369 bp += sizeof(align) - ((u_long)bp % sizeof(align));
234 370
235 if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 371 if (bp + n >= &hostbuf[sizeof hostbuf]) {
236#ifdef DEBUG 372#ifdef DEBUG
237 if (_res.options & RES_DEBUG) 373 if (_resp->options & RES_DEBUG)
238 printf("size (%d) too big\n", n); 374 printf("size (%d) too big\n", n);
239#endif 375#endif
376 had_error++;
377 continue;
378 }
379 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
380 if (!toobig++)
381#ifdef DEBUG
382 if (_resp->options & RES_DEBUG)
383 printf("Too many addresses (%d)\n", MAXADDRS);
384#endif
385 cp += n;
386 continue;
387 }
388 bcopy(cp, *hap++ = bp, n);
389 bp += n;
390 cp += n;
240 break; 391 break;
241 } 392 }
242 bcopy(cp, *hap++ = bp, n); 393 if (!had_error)
243 bp +=n; 394 haveanswer++;
244 cp += n;
245 haveanswer++;
246 } 395 }
247 if (haveanswer) { 396 if (haveanswer) {
248 *ap = NULL; 397 *ap = NULL;
249 *hap = NULL; 398 *hap = NULL;
250 if (_res.nsort) { 399# if defined(RESOLVSORT)
251 qsort(host.h_addr_list, haveanswer, 400 /*
252 sizeof(struct in_addr), 401 * Note: we sort even if host can take only one address
253 (int (*)__P((const void *, const void *)))qcomp); 402 * in its return structures - should give it the "best"
403 * address in that case, not some random one
404 */
405 if (_resp->nsort && haveanswer > 1 && qtype == T_A)
406 addrsort(h_addr_ptrs, haveanswer);
407# endif /*RESOLVSORT*/
408 if (!host.h_name) {
409 size_t len;
410
411 len = strlen(qname) + 1;
412 if (len > ep - bp) /* for the \0 */
413 goto try_again;
414 strlcpy(bp, qname, ep - bp);
415 host.h_name = bp;
416 bp += len;
254 } 417 }
418 if (_resp->options & RES_USE_INET6)
419 map_v4v6_hostent(&host, &bp, ep);
420 h_errno = NETDB_SUCCESS;
255 return (&host); 421 return (&host);
256 } else {
257 h_errno = TRY_AGAIN;
258 return ((struct hostent *) NULL);
259 } 422 }
423 try_again:
424 h_errno = TRY_AGAIN;
425 return (NULL);
260} 426}
261 427
428#ifdef notyet
429/*
430 * XXX This is an extremely bogus implementation.
431 *
432 * FreeBSD has this interface:
433 * int gethostbyaddr_r(const char *addr, int len, int type,
434 * struct hostent *result, struct hostent_data *buffer)
435 */
436
437struct hostent *
438gethostbyname_r(const char *name, struct hostent *hp, char *buf, int buflen,
439 int *errorp)
440{
441 struct hostent *res;
442
443 res = gethostbyname(name);
444 *errorp = h_errno;
445 if (res == NULL)
446 return NULL;
447 memcpy(hp, res, sizeof *hp); /* XXX not sufficient */
448 return hp;
449}
450
451/*
452 * XXX This is an extremely bogus implementation.
453 */
262struct hostent * 454struct hostent *
263gethostbyname(name) 455gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
264 const char *name; 456 char *buf, int buflen, int *errorp)
265{ 457{
266 querybuf buf; 458 struct hostent * res;
267 register const char *cp; 459
268 int n, i; 460 res = gethostbyaddr(addr, len, af);
269 extern struct hostent *_gethtbyname(), *_yp_gethtbyname(); 461 *errorp = h_errno;
270 register struct hostent *hp; 462 if (res == NULL)
463 return NULL;
464 memcpy(he, res, sizeof *he); /* XXX not sufficient */
465 return he;
466}
467
468/* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */
469#endif
470
471struct hostent *
472gethostbyname(const char *name)
473{
474 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
475 struct hostent *hp;
476 extern struct hostent *_gethtbyname2(const char *, int);
477
478 if (_res_init(0) == -1)
479 hp = _gethtbyname2(name, AF_INET);
480
481 else if (_resp->options & RES_USE_INET6) {
482 hp = gethostbyname2(name, AF_INET6);
483 if (hp == NULL)
484 hp = gethostbyname2(name, AF_INET);
485 }
486 else
487 hp = gethostbyname2(name, AF_INET);
488 return hp;
489}
490
491struct hostent *
492gethostbyname2(const char *name, int af)
493{
494 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
495 querybuf *buf;
496 const char *cp;
497 char *bp, *ep;
498 int n, size, type, i;
499 struct hostent *hp;
271 char lookups[MAXDNSLUS]; 500 char lookups[MAXDNSLUS];
501 extern struct hostent *_gethtbyname2(const char *, int);
502#ifdef YP
503 extern struct hostent *_yp_gethtbyname(const char *);
504#endif
505
506 if (_res_init(0) == -1)
507 return (_gethtbyname2(name, af));
508
509 switch (af) {
510 case AF_INET:
511 size = INADDRSZ;
512 type = T_A;
513 break;
514 case AF_INET6:
515 size = IN6ADDRSZ;
516 type = T_AAAA;
517 break;
518 default:
519 h_errno = NETDB_INTERNAL;
520 errno = EAFNOSUPPORT;
521 return (NULL);
522 }
523
524 host.h_addrtype = af;
525 host.h_length = size;
526
527 /*
528 * if there aren't any dots, it could be a user-level alias.
529 * this is also done in res_query() since we are not the only
530 * function that looks up host names.
531 */
532 if (!strchr(name, '.') && (cp = __hostalias(name)))
533 name = cp;
272 534
273 /* 535 /*
274 * disallow names consisting only of digits/dots, unless 536 * disallow names consisting only of digits/dots, unless
@@ -284,122 +546,229 @@ gethostbyname(name)
284 * Fake up a hostent as if we'd actually 546 * Fake up a hostent as if we'd actually
285 * done a lookup. 547 * done a lookup.
286 */ 548 */
287 if (!inet_aton(name, &host_addr)) { 549 if (inet_pton(af, name, host_addr) <= 0) {
288 h_errno = HOST_NOT_FOUND; 550 h_errno = HOST_NOT_FOUND;
289 return((struct hostent *) NULL); 551 return (NULL);
290 } 552 }
291 host.h_name = (char *)name; 553 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
554 bp = hostbuf + MAXHOSTNAMELEN;
555 ep = hostbuf + sizeof(hostbuf);
556 host.h_name = hostbuf;
292 host.h_aliases = host_aliases; 557 host.h_aliases = host_aliases;
293 host_aliases[0] = NULL; 558 host_aliases[0] = NULL;
294 host.h_addrtype = AF_INET; 559 h_addr_ptrs[0] = (char *)host_addr;
295 host.h_length = sizeof(u_int32_t);
296 h_addr_ptrs[0] = (char *)&host_addr;
297 h_addr_ptrs[1] = NULL; 560 h_addr_ptrs[1] = NULL;
298 host.h_addr_list = h_addr_ptrs; 561 host.h_addr_list = h_addr_ptrs;
562 if (_resp->options & RES_USE_INET6)
563 map_v4v6_hostent(&host, &bp, ep);
564 h_errno = NETDB_SUCCESS;
299 return (&host); 565 return (&host);
300 } 566 }
301 if (!isdigit(*cp) && *cp != '.') 567 if (!isdigit(*cp) && *cp != '.')
302 break; 568 break;
303 } 569 }
570 if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
571 name[0] == ':')
572 for (cp = name;; ++cp) {
573 if (!*cp) {
574 if (*--cp == '.')
575 break;
576 /*
577 * All-IPv6-legal, no dot at the end.
578 * Fake up a hostent as if we'd actually
579 * done a lookup.
580 */
581 if (inet_pton(af, name, host_addr) <= 0) {
582 h_errno = HOST_NOT_FOUND;
583 return (NULL);
584 }
585 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
586 bp = hostbuf + MAXHOSTNAMELEN;
587 ep = hostbuf + sizeof(hostbuf);
588 host.h_name = hostbuf;
589 host.h_aliases = host_aliases;
590 host_aliases[0] = NULL;
591 h_addr_ptrs[0] = (char *)host_addr;
592 h_addr_ptrs[1] = NULL;
593 host.h_addr_list = h_addr_ptrs;
594 h_errno = NETDB_SUCCESS;
595 return (&host);
596 }
597 if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
598 break;
599 }
304 600
305 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 601 bcopy(_resp->lookups, lookups, sizeof lookups);
306 return (_gethtbyname(name));
307
308 bcopy(_res.lookups, lookups, sizeof lookups);
309 if (lookups[0] == '\0') 602 if (lookups[0] == '\0')
310 strncpy(lookups, "bf", sizeof lookups); 603 strlcpy(lookups, "bf", sizeof lookups);
311 604
312 hp = (struct hostent *)NULL; 605 hp = (struct hostent *)NULL;
313 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { 606 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
314 switch (lookups[i]) { 607 switch (lookups[i]) {
315#ifdef YP 608#ifdef YP
316 case 'y': 609 case 'y':
317 hp = _yp_gethtbyname(name); 610 /* YP only supports AF_INET. */
611 if (af == AF_INET)
612 hp = _yp_gethtbyname(name);
318 break; 613 break;
319#endif 614#endif
320 case 'b': 615 case 'b':
321 if ((n = res_search(name, C_IN, T_A, buf.buf, 616 buf = malloc(sizeof(*buf));
322 sizeof(buf))) < 0) { 617 if (buf == NULL)
618 break;
619 if ((n = res_search(name, C_IN, type, buf->buf,
620 sizeof(buf->buf))) < 0) {
621 free(buf);
323#ifdef DEBUG 622#ifdef DEBUG
324 if (_res.options & RES_DEBUG) 623 if (_resp->options & RES_DEBUG)
325 printf("res_search failed\n"); 624 printf("res_search failed\n");
326#endif 625#endif
327 break; 626 break;
328 } 627 }
329 hp = getanswer(&buf, n, 0); 628 hp = getanswer(buf, n, name, type);
629 free(buf);
330 break; 630 break;
331 case 'f': 631 case 'f':
332 hp = _gethtbyname(name); 632 hp = _gethtbyname2(name, af);
333 break; 633 break;
334 } 634 }
335 } 635 }
636 /* XXX h_errno not correct in all cases... */
336 return (hp); 637 return (hp);
337} 638}
338 639
339struct hostent * 640struct hostent *
340gethostbyaddr(addr, len, type) 641gethostbyaddr(const void *addr, socklen_t len, int af)
341 const char *addr;
342 int len, type;
343{ 642{
344 int n, i; 643 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
345 querybuf buf; 644 const u_char *uaddr = (const u_char *)addr;
346 register struct hostent *hp; 645 int n, size, i;
347 char qbuf[MAXDNAME]; 646 querybuf *buf;
348 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); 647 struct hostent *hp;
648 char qbuf[MAXDNAME+1], *qp, *ep;
349 char lookups[MAXDNSLUS]; 649 char lookups[MAXDNSLUS];
650 struct hostent *res;
651 extern struct hostent *_gethtbyaddr(const void *, socklen_t, int);
652#ifdef YP
653 extern struct hostent *_yp_gethtbyaddr(const void *);
654#endif
350 655
351 if (type != AF_INET) 656 if (_res_init(0) == -1) {
352 return ((struct hostent *) NULL); 657 res = _gethtbyaddr(addr, len, af);
353 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", 658 return (res);
354 ((unsigned)addr[3] & 0xff), 659 }
355 ((unsigned)addr[2] & 0xff), 660
356 ((unsigned)addr[1] & 0xff), 661 if (af == AF_INET6 && len == IN6ADDRSZ &&
357 ((unsigned)addr[0] & 0xff)); 662 (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)uaddr) ||
358 663 IN6_IS_ADDR_SITELOCAL((struct in6_addr *)uaddr))) {
359 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 664 h_errno = HOST_NOT_FOUND;
360 return (_gethtbyaddr(addr, len, type)); 665 return (NULL);
361 666 }
362 bcopy(_res.lookups, lookups, sizeof lookups); 667 if (af == AF_INET6 && len == IN6ADDRSZ &&
668 (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)uaddr) ||
669 IN6_IS_ADDR_V4COMPAT((struct in6_addr *)uaddr))) {
670 /* Unmap. */
671 uaddr += IN6ADDRSZ - INADDRSZ;
672 af = AF_INET;
673 len = INADDRSZ;
674 }
675 switch (af) {
676 case AF_INET:
677 size = INADDRSZ;
678 break;
679 case AF_INET6:
680 size = IN6ADDRSZ;
681 break;
682 default:
683 errno = EAFNOSUPPORT;
684 h_errno = NETDB_INTERNAL;
685 return (NULL);
686 }
687 if (size != len) {
688 errno = EINVAL;
689 h_errno = NETDB_INTERNAL;
690 return (NULL);
691 }
692 ep = qbuf + sizeof(qbuf);
693 switch (af) {
694 case AF_INET:
695 (void) snprintf(qbuf, sizeof qbuf, "%u.%u.%u.%u.in-addr.arpa",
696 (uaddr[3] & 0xff), (uaddr[2] & 0xff),
697 (uaddr[1] & 0xff), (uaddr[0] & 0xff));
698 break;
699 case AF_INET6:
700 qp = qbuf;
701 for (n = IN6ADDRSZ - 1; n >= 0; n--) {
702 i = snprintf(qp, ep - qp, "%x.%x.",
703 uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
704 if (i <= 0 || i >= ep - qp) {
705 errno = EINVAL;
706 h_errno = NETDB_INTERNAL;
707 return (NULL);
708 }
709 qp += i;
710 }
711 strlcpy(qp, "ip6.arpa", ep - qp);
712 break;
713 }
714
715 bcopy(_resp->lookups, lookups, sizeof lookups);
363 if (lookups[0] == '\0') 716 if (lookups[0] == '\0')
364 strncpy(lookups, "bf", sizeof lookups); 717 strlcpy(lookups, "bf", sizeof lookups);
365 718
366 hp = (struct hostent *)NULL; 719 hp = (struct hostent *)NULL;
367 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { 720 for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
368 switch (lookups[i]) { 721 switch (lookups[i]) {
369#ifdef YP 722#ifdef YP
370 case 'y': 723 case 'y':
371 hp = _yp_gethtbyaddr(addr, len, type); 724 /* YP only supports AF_INET. */
725 if (af == AF_INET)
726 hp = _yp_gethtbyaddr(uaddr);
372 break; 727 break;
373#endif 728#endif
374 case 'b': 729 case 'b':
375 n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); 730 buf = malloc(sizeof(*buf));
731 if (!buf)
732 break;
733 n = res_query(qbuf, C_IN, T_PTR, buf->buf,
734 sizeof(buf->buf));
376 if (n < 0) { 735 if (n < 0) {
736 free(buf);
377#ifdef DEBUG 737#ifdef DEBUG
378 if (_res.options & RES_DEBUG) 738 if (_resp->options & RES_DEBUG)
379 printf("res_query failed\n"); 739 printf("res_query failed\n");
380#endif 740#endif
381 break; 741 break;
382 } 742 }
383 hp = getanswer(&buf, n, 1); 743 if (!(hp = getanswer(buf, n, qbuf, T_PTR))) {
384 if (hp == NULL) 744 free(buf);
385 break; 745 break;
386 hp->h_addrtype = type; 746 }
747 free(buf);
748 hp->h_addrtype = af;
387 hp->h_length = len; 749 hp->h_length = len;
388 h_addr_ptrs[0] = (char *)&host_addr; 750 bcopy(uaddr, host_addr, len);
389 h_addr_ptrs[1] = (char *)0; 751 h_addr_ptrs[0] = (char *)host_addr;
390 host_addr = *(struct in_addr *)addr; 752 h_addr_ptrs[1] = NULL;
753 if (af == AF_INET && (_resp->options & RES_USE_INET6)) {
754 map_v4v6_address((char*)host_addr,
755 (char*)host_addr);
756 hp->h_addrtype = AF_INET6;
757 hp->h_length = IN6ADDRSZ;
758 }
759 h_errno = NETDB_SUCCESS;
391 break; 760 break;
392 case 'f': 761 case 'f':
393 hp = _gethtbyaddr(addr, len, type); 762 hp = _gethtbyaddr(uaddr, len, af);
394 break; 763 break;
395 } 764 }
396 } 765 }
766 /* XXX h_errno not correct in all cases... */
397 return (hp); 767 return (hp);
398} 768}
399 769
400void 770void
401_sethtent(f) 771_sethtent(int f)
402 int f;
403{ 772{
404 if (hostf == NULL) 773 if (hostf == NULL)
405 hostf = fopen(_PATH_HOSTS, "r" ); 774 hostf = fopen(_PATH_HOSTS, "r" );
@@ -409,7 +778,7 @@ _sethtent(f)
409} 778}
410 779
411void 780void
412_endhtent() 781_endhtent(void)
413{ 782{
414 if (hostf && !stayopen) { 783 if (hostf && !stayopen) {
415 (void) fclose(hostf); 784 (void) fclose(hostf);
@@ -417,40 +786,66 @@ _endhtent()
417 } 786 }
418} 787}
419 788
420struct hostent * 789static struct hostent *
421_gethtent() 790_gethtent(void)
422{ 791{
423 char *p; 792 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
424 register char *cp, **q; 793 char *p, *cp, **q;
794 int af;
795 size_t len;
425 796
426 if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) 797 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
798 h_errno = NETDB_INTERNAL;
427 return (NULL); 799 return (NULL);
428again: 800 }
429 if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) 801 again:
802 if ((p = fgetln(hostf, &len)) == NULL) {
803 h_errno = HOST_NOT_FOUND;
430 return (NULL); 804 return (NULL);
431 if (*p == '#') 805 }
806 if (p[len-1] == '\n')
807 len--;
808 if (len >= sizeof(hostbuf) || len == 0)
432 goto again; 809 goto again;
433 cp = strpbrk(p, "#\n"); 810 p = memcpy(hostbuf, p, len);
434 if (cp == NULL) 811 hostbuf[len] = '\0';
812 if (*p == '#')
435 goto again; 813 goto again;
436 *cp = '\0'; 814 if ((cp = strchr(p, '#')))
437 cp = strpbrk(p, " \t"); 815 *cp = '\0';
438 if (cp == NULL) 816 if (!(cp = strpbrk(p, " \t")))
439 goto again; 817 goto again;
440 *cp++ = '\0'; 818 *cp++ = '\0';
441 /* THIS STUFF IS INTERNET SPECIFIC */ 819 if (inet_pton(AF_INET6, p, host_addr) > 0) {
442 h_addr_ptrs[0] = (char *)&host_addr; 820 af = AF_INET6;
821 len = IN6ADDRSZ;
822 } else if (inet_pton(AF_INET, p, host_addr) > 0) {
823 if (_resp->options & RES_USE_INET6) {
824 map_v4v6_address((char*)host_addr, (char*)host_addr);
825 af = AF_INET6;
826 len = IN6ADDRSZ;
827 } else {
828 af = AF_INET;
829 len = INADDRSZ;
830 }
831 } else {
832 goto again;
833 }
834 /* if this is not something we're looking for, skip it. */
835 if (host.h_addrtype != AF_UNSPEC && host.h_addrtype != af)
836 goto again;
837 if (host.h_length != 0 && host.h_length != len)
838 goto again;
839 h_addr_ptrs[0] = (char *)host_addr;
443 h_addr_ptrs[1] = NULL; 840 h_addr_ptrs[1] = NULL;
444 (void) inet_aton(p, &host_addr);
445 host.h_addr_list = h_addr_ptrs; 841 host.h_addr_list = h_addr_ptrs;
446 host.h_length = sizeof(u_int32_t); 842 host.h_length = len;
447 host.h_addrtype = AF_INET; 843 host.h_addrtype = af;
448 while (*cp == ' ' || *cp == '\t') 844 while (*cp == ' ' || *cp == '\t')
449 cp++; 845 cp++;
450 host.h_name = cp; 846 host.h_name = cp;
451 q = host.h_aliases = host_aliases; 847 q = host.h_aliases = host_aliases;
452 cp = strpbrk(cp, " \t"); 848 if ((cp = strpbrk(cp, " \t")))
453 if (cp != NULL)
454 *cp++ = '\0'; 849 *cp++ = '\0';
455 while (cp && *cp) { 850 while (cp && *cp) {
456 if (*cp == ' ' || *cp == '\t') { 851 if (*cp == ' ' || *cp == '\t') {
@@ -459,74 +854,61 @@ again:
459 } 854 }
460 if (q < &host_aliases[MAXALIASES - 1]) 855 if (q < &host_aliases[MAXALIASES - 1])
461 *q++ = cp; 856 *q++ = cp;
462 cp = strpbrk(cp, " \t"); 857 if ((cp = strpbrk(cp, " \t")))
463 if (cp != NULL)
464 *cp++ = '\0'; 858 *cp++ = '\0';
465 } 859 }
466 *q = NULL; 860 *q = NULL;
861 if (_resp->options & RES_USE_INET6) {
862 char *bp = hostbuf;
863 char *ep = hostbuf + sizeof hostbuf;
864
865 map_v4v6_hostent(&host, &bp, ep);
866 }
867 h_errno = NETDB_SUCCESS;
467 return (&host); 868 return (&host);
468} 869}
469 870
470struct hostent * 871struct hostent *
471_gethtbyname(name) 872_gethtbyname2(const char *name, int af)
472 char *name;
473{ 873{
474 register struct hostent *p; 874 struct hostent *p;
475 register char **cp; 875 char **cp;
476 876
477 _sethtent(0); 877 _sethtent(0);
478 while (p = _gethtent()) { 878 while ((p = _gethtent())) {
879 if (p->h_addrtype != af)
880 continue;
479 if (strcasecmp(p->h_name, name) == 0) 881 if (strcasecmp(p->h_name, name) == 0)
480 break; 882 break;
481 for (cp = p->h_aliases; *cp != 0; cp++) 883 for (cp = p->h_aliases; *cp != 0; cp++)
482 if (strcasecmp(*cp, name) == 0) 884 if (strcasecmp(*cp, name) == 0)
483 goto found; 885 goto found;
484 } 886 }
485found: 887 found:
486 _endhtent(); 888 _endhtent();
487 if (p==NULL)
488 h_errno = HOST_NOT_FOUND;
489 return (p); 889 return (p);
490} 890}
491 891
492struct hostent * 892struct hostent *
493_gethtbyaddr(addr, len, type) 893_gethtbyaddr(const void *addr, socklen_t len, int af)
494 const char *addr;
495 int len, type;
496{ 894{
497 register struct hostent *p; 895 struct hostent *p;
896
897 host.h_length = len;
898 host.h_addrtype = af;
498 899
499 _sethtent(0); 900 _sethtent(0);
500 while (p = _gethtent()) 901 while ((p = _gethtent()))
501 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) 902 if (p->h_addrtype == af && p->h_length == len &&
903 !bcmp(p->h_addr, addr, len))
502 break; 904 break;
503 _endhtent(); 905 _endhtent();
504 if (p==NULL)
505 h_errno = HOST_NOT_FOUND;
506 return (p); 906 return (p);
507} 907}
508 908
509static int
510qcomp(a1, a2)
511 struct in_addr **a1, **a2;
512{
513 int pos1, pos2;
514
515 for (pos1 = 0; pos1 < _res.nsort; pos1++)
516 if (_res.sort_list[pos1].addr.s_addr ==
517 ((*a1)->s_addr & _res.sort_list[pos1].mask))
518 break;
519 for (pos2 = 0; pos2 < _res.nsort; pos2++)
520 if (_res.sort_list[pos2].addr.s_addr ==
521 ((*a2)->s_addr & _res.sort_list[pos2].mask))
522 break;
523 return pos1 - pos2;
524}
525
526#ifdef YP 909#ifdef YP
527struct hostent * 910struct hostent *
528_yphostent(line) 911_yphostent(char *line)
529 char *line;
530{ 912{
531 static struct in_addr host_addrs[MAXADDRS]; 913 static struct in_addr host_addrs[MAXADDRS];
532 char *p = line; 914 char *p = line;
@@ -537,21 +919,21 @@ _yphostent(line)
537 919
538 host.h_name = NULL; 920 host.h_name = NULL;
539 host.h_addr_list = h_addr_ptrs; 921 host.h_addr_list = h_addr_ptrs;
540 host.h_length = sizeof(u_int32_t); 922 host.h_length = INADDRSZ;
541 host.h_addrtype = AF_INET; 923 host.h_addrtype = AF_INET;
542 hap = h_addr_ptrs; 924 hap = h_addr_ptrs;
543 buf = host_addrs; 925 buf = host_addrs;
544 q = host.h_aliases = host_aliases; 926 q = host.h_aliases = host_aliases;
545 927
546nextline: 928nextline:
929 /* check for host_addrs overflow */
930 if (buf >= &host_addrs[sizeof(host_addrs) / sizeof(host_addrs[0])])
931 goto done;
932
547 more = 0; 933 more = 0;
548 cp = strpbrk(p, " \t"); 934 cp = strpbrk(p, " \t");
549 if (cp == NULL) { 935 if (cp == NULL)
550 if (host.h_name == NULL) 936 goto done;
551 return (NULL);
552 else
553 goto done;
554 }
555 *cp++ = '\0'; 937 *cp++ = '\0';
556 938
557 *hap++ = (char *)buf; 939 *hap++ = (char *)buf;
@@ -592,30 +974,28 @@ nextline:
592 *cp++ = '\0'; 974 *cp++ = '\0';
593 } 975 }
594done: 976done:
977 if (host.h_name == NULL)
978 return (NULL);
595 *q = NULL; 979 *q = NULL;
596 *hap = NULL; 980 *hap = NULL;
597 return (&host); 981 return (&host);
598} 982}
599 983
600struct hostent * 984struct hostent *
601_yp_gethtbyaddr(addr, len, type) 985_yp_gethtbyaddr(const void *addr)
602 const char *addr;
603 int len, type;
604{ 986{
605 struct hostent *hp = (struct hostent *)NULL; 987 struct hostent *hp = NULL;
988 const u_char *uaddr = (const u_char *)addr;
606 static char *__ypcurrent; 989 static char *__ypcurrent;
607 int __ypcurrentlen, r; 990 int __ypcurrentlen, r;
608 char name[sizeof("xxx.xxx.xxx.xxx") + 1]; 991 char name[sizeof("xxx.xxx.xxx.xxx")];
609 992
610 if (!__ypdomain) { 993 if (!__ypdomain) {
611 if (_yp_check(&__ypdomain) == 0) 994 if (_yp_check(&__ypdomain) == 0)
612 return (hp); 995 return (hp);
613 } 996 }
614 sprintf(name, "%u.%u.%u.%u", 997 snprintf(name, sizeof name, "%u.%u.%u.%u", (uaddr[0] & 0xff),
615 ((unsigned)addr[0] & 0xff), 998 (uaddr[1] & 0xff), (uaddr[2] & 0xff), (uaddr[3] & 0xff));
616 ((unsigned)addr[1] & 0xff),
617 ((unsigned)addr[2] & 0xff),
618 ((unsigned)addr[3] & 0xff));
619 if (__ypcurrent) 999 if (__ypcurrent)
620 free(__ypcurrent); 1000 free(__ypcurrent);
621 __ypcurrent = NULL; 1001 __ypcurrent = NULL;
@@ -629,13 +1009,14 @@ _yp_gethtbyaddr(addr, len, type)
629} 1009}
630 1010
631struct hostent * 1011struct hostent *
632_yp_gethtbyname(name) 1012_yp_gethtbyname(const char *name)
633 const char *name;
634{ 1013{
635 struct hostent *hp = (struct hostent *)NULL; 1014 struct hostent *hp = (struct hostent *)NULL;
636 static char *__ypcurrent; 1015 static char *__ypcurrent;
637 int __ypcurrentlen, r; 1016 int __ypcurrentlen, r;
638 1017
1018 if (strlen(name) >= MAXHOSTNAMELEN)
1019 return (NULL);
639 if (!__ypdomain) { 1020 if (!__ypdomain) {
640 if (_yp_check(&__ypdomain) == 0) 1021 if (_yp_check(&__ypdomain) == 0)
641 return (hp); 1022 return (hp);
@@ -645,10 +1026,104 @@ _yp_gethtbyname(name)
645 __ypcurrent = NULL; 1026 __ypcurrent = NULL;
646 r = yp_match(__ypdomain, "hosts.byname", name, 1027 r = yp_match(__ypdomain, "hosts.byname", name,
647 strlen(name), &__ypcurrent, &__ypcurrentlen); 1028 strlen(name), &__ypcurrent, &__ypcurrentlen);
648 if (r==0) 1029 if (r == 0)
649 hp = _yphostent(__ypcurrent); 1030 hp = _yphostent(__ypcurrent);
650 if (hp==NULL) 1031 if (hp == NULL)
651 h_errno = HOST_NOT_FOUND; 1032 h_errno = HOST_NOT_FOUND;
652 return (hp); 1033 return (hp);
653} 1034}
654#endif 1035#endif
1036
1037static void
1038map_v4v6_address(const char *src, char *dst)
1039{
1040 u_char *p = (u_char *)dst;
1041 char tmp[INADDRSZ];
1042 int i;
1043
1044 /* Stash a temporary copy so our caller can update in place. */
1045 bcopy(src, tmp, INADDRSZ);
1046 /* Mark this ipv6 addr as a mapped ipv4. */
1047 for (i = 0; i < 10; i++)
1048 *p++ = 0x00;
1049 *p++ = 0xff;
1050 *p++ = 0xff;
1051 /* Retrieve the saved copy and we're done. */
1052 bcopy(tmp, (void*)p, INADDRSZ);
1053}
1054
1055static void
1056map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep)
1057{
1058 char **ap;
1059
1060 if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
1061 return;
1062 hp->h_addrtype = AF_INET6;
1063 hp->h_length = IN6ADDRSZ;
1064 for (ap = hp->h_addr_list; *ap; ap++) {
1065 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1066
1067 if (ep - *bpp < (i + IN6ADDRSZ)) {
1068 /* Out of memory. Truncate address list here. XXX */
1069 *ap = NULL;
1070 return;
1071 }
1072 *bpp += i;
1073 map_v4v6_address(*ap, *bpp);
1074 *ap = *bpp;
1075 *bpp += IN6ADDRSZ;
1076 }
1077}
1078
1079struct hostent *
1080gethostent(void)
1081{
1082 host.h_addrtype = AF_UNSPEC;
1083 host.h_length = 0;
1084 return (_gethtent());
1085}
1086
1087#ifdef RESOLVSORT
1088static void
1089addrsort(char **ap, int num)
1090{
1091 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
1092 int i, j;
1093 char **p;
1094 short aval[MAXADDRS];
1095 int needsort = 0;
1096
1097 p = ap;
1098 for (i = 0; i < num; i++, p++) {
1099 for (j = 0 ; (unsigned)j < _resp->nsort; j++)
1100 if (_resp->sort_list[j].addr.s_addr ==
1101 (((struct in_addr *)(*p))->s_addr &
1102 _resp->sort_list[j].mask))
1103 break;
1104 aval[i] = j;
1105 if (needsort == 0 && i > 0 && j < aval[i-1])
1106 needsort = i;
1107 }
1108 if (!needsort)
1109 return;
1110
1111 while (needsort < num) {
1112 for (j = needsort - 1; j >= 0; j--) {
1113 if (aval[j] > aval[j+1]) {
1114 char *hp;
1115
1116 i = aval[j];
1117 aval[j] = aval[j+1];
1118 aval[j+1] = i;
1119
1120 hp = ap[j];
1121 ap[j] = ap[j+1];
1122 ap[j+1] = hp;
1123 } else
1124 break;
1125 }
1126 needsort++;
1127 }
1128}
1129#endif
diff --git a/src/lib/libc/net/getifaddrs.3 b/src/lib/libc/net/getifaddrs.3
new file mode 100644
index 0000000000..f282e26960
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.3
@@ -0,0 +1,157 @@
1.\" $OpenBSD: getifaddrs.3,v 1.14 2007/05/31 19:19:30 jmc Exp $
2.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp
3.\"
4.\" Copyright (c) 1995, 1999
5.\" Berkeley Software Design, Inc. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.Dd $Mdocdate: May 31 2007 $
25.Dt GETIFADDRS 3
26.Os
27.Sh NAME
28.Nm getifaddrs
29.Nd get interface addresses
30.Sh SYNOPSIS
31.Fd #include <sys/types.h>
32.Fd #include <sys/socket.h>
33.Fd #include <ifaddrs.h>
34.Ft int
35.Fn getifaddrs "struct ifaddrs **ifap"
36.Ft void
37.Fn freeifaddrs "struct ifaddrs *ifap"
38.Sh DESCRIPTION
39The
40.Fn getifaddrs
41function stores a reference to a linked list of the network interfaces
42on the local machine in the memory referenced by
43.Fa ifap .
44The list consists of
45.Nm ifaddrs
46structures, as defined in the include file
47.Aq Pa ifaddrs.h .
48The
49.Nm ifaddrs
50structure contains at least the following entries:
51.Bd -literal
52 struct ifaddrs *ifa_next; /* Pointer to next struct */
53 char *ifa_name; /* Interface name */
54 u_int ifa_flags; /* Interface flags */
55 struct sockaddr *ifa_addr; /* Interface address */
56 struct sockaddr *ifa_netmask; /* Interface netmask */
57 struct sockaddr *ifa_broadaddr; /* Interface broadcast address */
58 struct sockaddr *ifa_dstaddr; /* P2P interface destination */
59 void *ifa_data; /* Address specific data */
60.Ed
61.Bl -tag -width ifa_broadaddr
62.It Fa ifa_next
63Contains a pointer to the next structure on the list.
64This field is set to
65.Dv NULL
66in the last structure on the list.
67.It Fa ifa_name
68Contains the interface name.
69.It Fa ifa_flags
70Contains the interface flags, as set by
71.Xr ifconfig 8 .
72.It Fa ifa_addr
73References either the address of the interface or the link level
74address of the interface, if one exists, otherwise it is
75.Dv NULL .
76(The
77.Fa sa_family
78field of the
79.Fa ifa_addr
80field should be consulted to determine the format of the
81.Fa ifa_addr
82address.)
83.It Fa ifa_netmask
84References the netmask associated with
85.Fa ifa_addr ,
86if one is set, otherwise it is
87.Dv NULL .
88.It Fa ifa_broadaddr
89This field, which should only be referenced for non-P2P interfaces,
90references the broadcast address associated with
91.Fa ifa_addr ,
92if one exists, otherwise it is
93.Dv NULL .
94.It Fa ifa_dstaddr
95References the destination address on a P2P interface,
96if one exists, otherwise it is
97.Dv NULL .
98.It Fa ifa_data
99References address family specific data.
100For
101.Dv AF_LINK
102addresses it contains a pointer to the
103.Li struct if_data
104(as defined in include file
105.Aq Pa net/if.h )
106which contains various interface attributes and statistics.
107For all other address families,
108.Fa ifa_data
109is
110.Dv NULL .
111.El
112.Pp
113The data returned by
114.Fn getifaddrs
115is dynamically allocated and should be freed using
116.Fn freeifaddrs
117when no longer needed.
118.Sh RETURN VALUES
119Upon successful completion, a value of 0 is returned.
120Otherwise, a value of \-1 is returned and
121.Va errno
122is set to indicate the error.
123.Sh ERRORS
124The
125.Fn getifaddrs
126may fail and set
127.Va errno
128for any of the errors specified for the library routines
129.Xr ioctl 2 ,
130.Xr socket 2 ,
131.Xr malloc 3 ,
132or
133.Xr sysctl 3 .
134.Sh SEE ALSO
135.Xr ioctl 2 ,
136.Xr socket 2 ,
137.Xr sysctl 3 ,
138.Xr networking 4 ,
139.Xr ifconfig 8
140.Sh HISTORY
141The
142.Fn getifaddrs
143function first appeared in BSDI BSD/OS.
144The function has been available on
145.Ox
146since
147.Ox 2.7 .
148.Sh BUGS
149If both
150.Aq Pa net/if.h
151and
152.Aq Pa ifaddrs.h
153are being included,
154.Aq Pa net/if.h
155.Em must
156be included before
157.Aq Pa ifaddrs.h .
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c
new file mode 100644
index 0000000000..0db89f6c19
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.c
@@ -0,0 +1,277 @@
1/* $OpenBSD: getifaddrs.c,v 1.9 2002/08/09 06:12:25 itojun Exp $ */
2
3/*
4 * Copyright (c) 1995, 1999
5 * Berkeley Software Design, Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp
26 */
27
28#include <sys/types.h>
29#include <sys/ioctl.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <sys/param.h>
33#include <net/route.h>
34#include <sys/sysctl.h>
35#include <net/if_dl.h>
36
37#include <errno.h>
38#include <ifaddrs.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#define SALIGN (sizeof(long) - 1)
44#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
45
46int
47getifaddrs(struct ifaddrs **pif)
48{
49 int icnt = 1;
50 int dcnt = 0;
51 int ncnt = 0;
52 int mib[6];
53 size_t needed;
54 char *buf;
55 char *next;
56 struct ifaddrs *cif = 0;
57 char *p, *p0;
58 struct rt_msghdr *rtm;
59 struct if_msghdr *ifm;
60 struct ifa_msghdr *ifam;
61 struct sockaddr_dl *dl;
62 struct sockaddr *sa;
63 u_short index = 0;
64 size_t len, alen;
65 struct ifaddrs *ifa, *ift;
66 int i;
67 char *data;
68 char *names;
69
70 mib[0] = CTL_NET;
71 mib[1] = PF_ROUTE;
72 mib[2] = 0; /* protocol */
73 mib[3] = 0; /* wildcard address family */
74 mib[4] = NET_RT_IFLIST;
75 mib[5] = 0; /* no flags */
76 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
77 return (-1);
78 if ((buf = malloc(needed)) == NULL)
79 return (-1);
80 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
81 free(buf);
82 return (-1);
83 }
84
85 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
86 rtm = (struct rt_msghdr *)next;
87 if (rtm->rtm_version != RTM_VERSION)
88 continue;
89 switch (rtm->rtm_type) {
90 case RTM_IFINFO:
91 ifm = (struct if_msghdr *)rtm;
92 if (ifm->ifm_addrs & RTA_IFP) {
93 index = ifm->ifm_index;
94 ++icnt;
95 dl = (struct sockaddr_dl *)(ifm + 1);
96 dcnt += SA_RLEN((struct sockaddr *)dl) +
97 ALIGNBYTES;
98 dcnt += sizeof(ifm->ifm_data);
99 ncnt += dl->sdl_nlen + 1;
100 } else
101 index = 0;
102 break;
103
104 case RTM_NEWADDR:
105 ifam = (struct ifa_msghdr *)rtm;
106 if (index && ifam->ifam_index != index)
107 abort(); /* XXX abort illegal in library */
108
109#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD)
110 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
111 break;
112 p = (char *)(ifam + 1);
113 ++icnt;
114 /* Scan to look for length of address */
115 alen = 0;
116 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
117 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
118 == 0)
119 continue;
120 sa = (struct sockaddr *)p;
121 len = SA_RLEN(sa);
122 if (i == RTAX_IFA) {
123 alen = len;
124 break;
125 }
126 p += len;
127 }
128 for (p = p0, i = 0; i < RTAX_MAX; i++) {
129 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
130 == 0)
131 continue;
132 sa = (struct sockaddr *)p;
133 len = SA_RLEN(sa);
134 if (i == RTAX_NETMASK && sa->sa_len == 0)
135 dcnt += alen;
136 else
137 dcnt += len;
138 p += len;
139 }
140 break;
141 }
142 }
143
144 if (icnt + dcnt + ncnt == 1) {
145 *pif = NULL;
146 free(buf);
147 return (0);
148 }
149 data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
150 if (data == NULL) {
151 free(buf);
152 return(-1);
153 }
154
155 ifa = (struct ifaddrs *)data;
156 data += sizeof(struct ifaddrs) * icnt;
157 names = data + dcnt;
158
159 memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
160 ift = ifa;
161
162 index = 0;
163 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
164 rtm = (struct rt_msghdr *)next;
165 if (rtm->rtm_version != RTM_VERSION)
166 continue;
167 switch (rtm->rtm_type) {
168 case RTM_IFINFO:
169 ifm = (struct if_msghdr *)rtm;
170 if (ifm->ifm_addrs & RTA_IFP) {
171 index = ifm->ifm_index;
172 dl = (struct sockaddr_dl *)(ifm + 1);
173
174 cif = ift;
175 ift->ifa_name = names;
176 ift->ifa_flags = (int)ifm->ifm_flags;
177 memcpy(names, dl->sdl_data, dl->sdl_nlen);
178 names[dl->sdl_nlen] = 0;
179 names += dl->sdl_nlen + 1;
180
181 ift->ifa_addr = (struct sockaddr *)data;
182 memcpy(data, dl,
183 ((struct sockaddr *)dl)->sa_len);
184 data += SA_RLEN((struct sockaddr *)dl);
185
186 /* ifm_data needs to be aligned */
187 ift->ifa_data = data = (void *)ALIGN(data);
188 memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data));
189 data += sizeof(ifm->ifm_data);
190
191 ift = (ift->ifa_next = ift + 1);
192 } else
193 index = 0;
194 break;
195
196 case RTM_NEWADDR:
197 ifam = (struct ifa_msghdr *)rtm;
198 if (index && ifam->ifam_index != index)
199 abort(); /* XXX abort illegal in library */
200
201 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
202 break;
203 ift->ifa_name = cif->ifa_name;
204 ift->ifa_flags = cif->ifa_flags;
205 ift->ifa_data = NULL;
206 p = (char *)(ifam + 1);
207 /* Scan to look for length of address */
208 alen = 0;
209 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
210 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
211 == 0)
212 continue;
213 sa = (struct sockaddr *)p;
214 len = SA_RLEN(sa);
215 if (i == RTAX_IFA) {
216 alen = len;
217 break;
218 }
219 p += len;
220 }
221 for (p = p0, i = 0; i < RTAX_MAX; i++) {
222 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
223 == 0)
224 continue;
225 sa = (struct sockaddr *)p;
226 len = SA_RLEN(sa);
227 switch (i) {
228 case RTAX_IFA:
229 ift->ifa_addr = (struct sockaddr *)data;
230 memcpy(data, p, len);
231 data += len;
232 break;
233
234 case RTAX_NETMASK:
235 ift->ifa_netmask =
236 (struct sockaddr *)data;
237 if (sa->sa_len == 0) {
238 memset(data, 0, alen);
239 data += alen;
240 break;
241 }
242 memcpy(data, p, len);
243 data += len;
244 break;
245
246 case RTAX_BRD:
247 ift->ifa_broadaddr =
248 (struct sockaddr *)data;
249 memcpy(data, p, len);
250 data += len;
251 break;
252 }
253 p += len;
254 }
255
256
257 ift = (ift->ifa_next = ift + 1);
258 break;
259 }
260 }
261
262 free(buf);
263 if (--ift >= ifa) {
264 ift->ifa_next = NULL;
265 *pif = ifa;
266 } else {
267 *pif = NULL;
268 free(ifa);
269 }
270 return (0);
271}
272
273void
274freeifaddrs(struct ifaddrs *ifp)
275{
276 free(ifp);
277}
diff --git a/src/lib/libc/net/getnameinfo.3 b/src/lib/libc/net/getnameinfo.3
new file mode 100644
index 0000000000..9b7e591149
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.3
@@ -0,0 +1,266 @@
1.\" $OpenBSD: getnameinfo.3,v 1.40 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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.Fd #include <sys/types.h>
27.Fd #include <sys/socket.h>
28.Fd #include <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
33The
34.Fn getnameinfo
35function is used to convert a
36.Li sockaddr
37structure to a pair of host name and service strings.
38It is a replacement for and provides more flexibility than the
39.Xr gethostbyaddr 3
40and
41.Xr getservbyport 3
42functions and is the converse of the
43.Xr getaddrinfo 3
44function.
45.Pp
46The
47.Li sockaddr
48structure
49.Fa sa
50should point to either a
51.Li sockaddr_in
52or
53.Li sockaddr_in6
54structure (for IPv4 or IPv6 respectively) that is
55.Fa salen
56bytes long.
57.Pp
58The host and service names associated with
59.Fa sa
60are stored in
61.Fa host
62and
63.Fa serv
64which have length parameters
65.Fa hostlen
66and
67.Fa servlen .
68The maximum value for
69.Fa hostlen
70is
71.Dv NI_MAXHOST
72and
73the maximum value for
74.Fa servlen
75is
76.Dv NI_MAXSERV ,
77as defined by
78.Aq Pa netdb.h .
79If a length parameter is zero, no string will be stored.
80Otherwise, enough space must be provided to store the
81host name or service string plus a byte for the NUL terminator.
82.Pp
83The
84.Fa flags
85argument is formed by
86.Tn OR Ns 'ing
87the following values:
88.Bl -tag -width "NI_NUMERICHOSTXX"
89.It Dv NI_NOFQDN
90A fully qualified domain name is not required for local hosts.
91The local part of the fully qualified domain name is returned instead.
92.It Dv NI_NUMERICHOST
93Return the address in numeric form, as if calling
94.Xr inet_ntop 3 ,
95instead of a host name.
96.It Dv NI_NAMEREQD
97A name is required.
98If the host name cannot be found in DNS and this flag is set,
99a non-zero error code is returned.
100If the host name is not found and the flag is not set, the
101address is returned in numeric form.
102.It NI_NUMERICSERV
103The service name is returned as a digit string representing the port number.
104.It NI_DGRAM
105Specifies that the service being looked up is a datagram
106service, and causes
107.Xr getservbyport 3
108to be called with a second argument of
109.Dq udp
110instead of its default of
111.Dq tcp .
112This is required for the few ports (512\-514) that have different services
113for
114.Tn UDP
115and
116.Tn TCP .
117.El
118.Pp
119This implementation allows numeric IPv6 address notation with scope identifier,
120as documented in chapter 11 of draft-ietf-ipv6-scoping-arch-02.txt.
121IPv6 link-local address will appear as a string like
122.Dq Li fe80::1%ne0 .
123Refer to
124.Xr getaddrinfo 3
125for more information.
126.Sh RETURN VALUES
127.Fn getnameinfo
128returns zero on success or one of the error codes listed in
129.Xr gai_strerror 3
130if an error occurs.
131.Sh EXAMPLES
132The following code tries to get a numeric host name, and service name,
133for a given socket address.
134Observe that there is no hardcoded reference to a particular address family.
135.Bd -literal -offset indent
136struct sockaddr *sa; /* input */
137char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
138
139if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
140 sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV))
141 errx(1, "could not get numeric hostname");
142printf("host=%s, serv=%s\en", hbuf, sbuf);
143.Ed
144.Pp
145The following version checks if the socket address has a reverse address mapping:
146.Bd -literal -offset indent
147struct sockaddr *sa; /* input */
148char hbuf[NI_MAXHOST];
149
150if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
151 NI_NAMEREQD))
152 errx(1, "could not resolve hostname");
153printf("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 R. Gilligan
169.%A S. Thomson
170.%A J. Bound
171.%A W. Stevens
172.%T Basic Socket Interface Extensions for IPv6
173.%R RFC 2553
174.%D March 1999
175.Re
176.Rs
177.%A S. Deering
178.%A B. Haberman
179.%A T. Jinmei
180.%A E. Nordmark
181.%A B. Zill
182.%T "IPv6 Scoped Address Architecture"
183.%R internet draft
184.%N draft-ietf-ipv6-scoping-arch-02.txt
185.%O work in progress material
186.Re
187.Rs
188.%A Craig Metz
189.%T Protocol Independence Using the Sockets API
190.%B "Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference"
191.%D June 2000
192.Re
193.Sh STANDARDS
194The
195.Fn getnameinfo
196function is defined by the
197.St -p1003.1g-2000
198draft specification and documented in
199.Tn "RFC 2553" ,
200.Dq Basic Socket Interface Extensions for IPv6 .
201.Sh CAVEATS
202.Fn getnameinfo
203can return both numeric and FQDN forms of the address specified in
204.Fa sa .
205There is no return value that indicates whether the string returned in
206.Fa host
207is a result of binary to numeric-text translation (like
208.Xr inet_ntop 3 ) ,
209or is the result of a DNS reverse lookup.
210Because of this, malicious parties could set up a PTR record as follows:
211.Bd -literal -offset indent
2121.0.0.127.in-addr.arpa. IN PTR 10.1.1.1
213.Ed
214.Pp
215and trick the caller of
216.Fn getnameinfo
217into believing that
218.Fa sa
219is
220.Li 10.1.1.1
221when it is actually
222.Li 127.0.0.1 .
223.Pp
224To prevent such attacks, the use of
225.Dv NI_NAMEREQD
226is recommended when the result of
227.Fn getnameinfo
228is used
229for access control purposes:
230.Bd -literal -offset indent
231struct sockaddr *sa;
232socklen_t salen;
233char addr[NI_MAXHOST];
234struct addrinfo hints, *res;
235int error;
236
237error = getnameinfo(sa, salen, addr, sizeof(addr),
238 NULL, 0, NI_NAMEREQD);
239if (error == 0) {
240 memset(&hints, 0, sizeof(hints));
241 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
242 hints.ai_flags = AI_NUMERICHOST;
243 if (getaddrinfo(addr, "0", &hints, &res) == 0) {
244 /* malicious PTR record */
245 freeaddrinfo(res);
246 printf("bogus PTR record\en");
247 return -1;
248 }
249 /* addr is FQDN as a result of PTR lookup */
250} else {
251 /* addr is numeric string */
252 error = getnameinfo(sa, salen, addr, sizeof(addr),
253 NULL, 0, NI_NUMERICHOST);
254}
255.Ed
256.Sh BUGS
257The implementation of
258.Fn getnameinfo
259is not thread-safe.
260.Pp
261.Ox
262intentionally uses a different
263.Dv NI_MAXHOST
264value from what
265.Tn "RFC 2553"
266suggests, to avoid buffer length handling mistakes.
diff --git a/src/lib/libc/net/getnameinfo.c b/src/lib/libc/net/getnameinfo.c
new file mode 100644
index 0000000000..7041a4ee48
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.c
@@ -0,0 +1,351 @@
1/* $OpenBSD: getnameinfo.c,v 1.33 2007/02/15 04:25:35 ray Exp $ */
2/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Issues to be discussed:
35 * - Thread safe-ness must be checked
36 * - RFC2553 says that we should raise error on short buffer. X/Open says
37 * we need to truncate the result. We obey RFC2553 (and X/Open should be
38 * modified). ipngwg rough consensus seems to follow RFC2553.
39 * - What is "local" in NI_FQDN?
40 * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
41 * - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
42 * sin6_scope_id is filled - standardization status?
43 * XXX breaks backward compat for code that expects no scopeid.
44 * beware on merge.
45 */
46
47#ifndef INET6
48#define INET6
49#endif
50
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <net/if.h>
54#include <netinet/in.h>
55#include <arpa/inet.h>
56#include <arpa/nameser.h>
57#include <netdb.h>
58#include <resolv.h>
59#include <string.h>
60#include <stddef.h>
61
62#include "thread_private.h"
63
64static const struct afd {
65 int a_af;
66 int a_addrlen;
67 int a_socklen;
68 int a_off;
69} afdl [] = {
70#ifdef INET6
71 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
72 offsetof(struct sockaddr_in6, sin6_addr)},
73#endif
74 {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
75 offsetof(struct sockaddr_in, sin_addr)},
76 {0, 0, 0},
77};
78
79struct sockinet {
80 u_char si_len;
81 u_char si_family;
82 u_short si_port;
83};
84
85#ifdef INET6
86static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
87 size_t, int);
88static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
89#endif
90
91void *__THREAD_NAME(serv_mutex);
92
93int
94getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
95 size_t hostlen, char *serv, size_t servlen, int flags)
96{
97 const struct afd *afd;
98 struct hostent *hp;
99 u_short port;
100 int family, i;
101 const char *addr;
102 u_int32_t v4a;
103 char numserv[512];
104 char numaddr[512];
105
106 if (sa == NULL)
107 return EAI_FAIL;
108
109 family = sa->sa_family;
110 for (i = 0; afdl[i].a_af; i++)
111 if (afdl[i].a_af == family) {
112 afd = &afdl[i];
113 goto found;
114 }
115 return EAI_FAMILY;
116
117 found:
118 if (salen != afd->a_socklen)
119 return EAI_FAIL;
120
121 /* network byte order */
122 port = ((const struct sockinet *)sa)->si_port;
123 addr = (const char *)sa + afd->a_off;
124
125 if (serv == NULL || servlen == 0) {
126 /*
127 * do nothing in this case.
128 * in case you are wondering if "&&" is more correct than
129 * "||" here: rfc2553bis-03 says that serv == NULL OR
130 * servlen == 0 means that the caller does not want the result.
131 */
132 } else if (!(flags & NI_NUMERICSERV)) {
133 struct servent sp;
134 struct servent_data sd;
135
136 (void)memset(&sd, 0, sizeof(sd));
137 if (getservbyport_r(port,
138 (flags & NI_DGRAM) ? "udp" : "tcp", &sp, &sd) == -1)
139 goto numeric;
140
141 if (strlen(sp.s_name) + 1 > servlen) {
142 endservent_r(&sd);
143 return EAI_MEMORY;
144 }
145 strlcpy(serv, sp.s_name, servlen);
146 endservent_r(&sd);
147 } else {
148 numeric:
149 i = snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
150 if (i < 0 || i >= servlen || i >= sizeof(numserv))
151 return EAI_MEMORY;
152 strlcpy(serv, numserv, servlen);
153 }
154
155 switch (sa->sa_family) {
156 case AF_INET:
157 v4a = (u_int32_t)
158 ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
159 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
160 flags |= NI_NUMERICHOST;
161 v4a >>= IN_CLASSA_NSHIFT;
162 if (v4a == 0)
163 flags |= NI_NUMERICHOST;
164 break;
165#ifdef INET6
166 case AF_INET6:
167 {
168 const struct sockaddr_in6 *sin6;
169 sin6 = (const struct sockaddr_in6 *)sa;
170 switch (sin6->sin6_addr.s6_addr[0]) {
171 case 0x00:
172 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
173 ;
174 else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
175 ;
176 else
177 flags |= NI_NUMERICHOST;
178 break;
179 default:
180 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
181 flags |= NI_NUMERICHOST;
182 }
183 else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
184 flags |= NI_NUMERICHOST;
185 break;
186 }
187 }
188 break;
189#endif
190 }
191 if (host == NULL || hostlen == 0) {
192 /*
193 * do nothing in this case.
194 * in case you are wondering if "&&" is more correct than
195 * "||" here: rfc2553bis-03 says that host == NULL or
196 * hostlen == 0 means that the caller does not want the result.
197 */
198 } else if (flags & NI_NUMERICHOST) {
199 int numaddrlen;
200
201 /* NUMERICHOST and NAMEREQD conflicts with each other */
202 if (flags & NI_NAMEREQD)
203 return EAI_NONAME;
204
205 switch(afd->a_af) {
206#ifdef INET6
207 case AF_INET6:
208 {
209 int error;
210
211 if ((error = ip6_parsenumeric(sa, addr, host,
212 hostlen, flags)) != 0)
213 return(error);
214 break;
215 }
216#endif
217 default:
218 if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
219 == NULL)
220 return EAI_SYSTEM;
221 numaddrlen = strlen(numaddr);
222 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
223 return EAI_MEMORY;
224 strlcpy(host, numaddr, hostlen);
225 break;
226 }
227 } else {
228 _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
229 hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
230 _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
231
232 if (hp) {
233#if 0
234 /*
235 * commented out, since "for local host" is not
236 * implemented here - see RFC2553 p30
237 */
238 if (flags & NI_NOFQDN) {
239 char *p;
240 p = strchr(hp->h_name, '.');
241 if (p)
242 *p = '\0';
243 }
244#endif
245 if (strlen(hp->h_name) + 1 > hostlen) {
246 return EAI_MEMORY;
247 }
248 strlcpy(host, hp->h_name, hostlen);
249 } else {
250 if (flags & NI_NAMEREQD)
251 return EAI_NONAME;
252 switch(afd->a_af) {
253#ifdef INET6
254 case AF_INET6:
255 {
256 int error;
257
258 if ((error = ip6_parsenumeric(sa, addr, host,
259 hostlen,
260 flags)) != 0)
261 return(error);
262 break;
263 }
264#endif
265 default:
266 if (inet_ntop(afd->a_af, addr, host,
267 hostlen) == NULL)
268 return EAI_SYSTEM;
269 break;
270 }
271 }
272 }
273 return(0);
274}
275
276#ifdef INET6
277static int
278ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
279 size_t hostlen, int flags)
280{
281 int numaddrlen;
282 char numaddr[512];
283
284 if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
285 return EAI_SYSTEM;
286
287 numaddrlen = strlen(numaddr);
288 if (numaddrlen + 1 > hostlen) /* don't forget terminator */
289 return EAI_MEMORY;
290 strlcpy(host, numaddr, hostlen);
291
292 if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
293 char zonebuf[MAXHOSTNAMELEN];
294 int zonelen;
295
296 zonelen = ip6_sa2str(
297 (const struct sockaddr_in6 *)(const void *)sa,
298 zonebuf, sizeof(zonebuf), flags);
299 if (zonelen < 0)
300 return EAI_MEMORY;
301 if (zonelen + 1 + numaddrlen + 1 > hostlen)
302 return EAI_MEMORY;
303
304 /* construct <numeric-addr><delim><zoneid> */
305 memcpy(host + numaddrlen + 1, zonebuf,
306 (size_t)zonelen);
307 host[numaddrlen] = SCOPE_DELIMITER;
308 host[numaddrlen + 1 + zonelen] = '\0';
309 }
310
311 return 0;
312}
313
314/* ARGSUSED */
315static int
316ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
317{
318 unsigned int ifindex;
319 const struct in6_addr *a6;
320 int n;
321
322 ifindex = (unsigned int)sa6->sin6_scope_id;
323 a6 = &sa6->sin6_addr;
324
325#ifdef notdef
326 if ((flags & NI_NUMERICSCOPE) != 0) {
327 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
328 if (n < 0 || n >= bufsiz)
329 return -1;
330 else
331 return n;
332 }
333#endif
334
335 /* if_indextoname() does not take buffer size. not a good api... */
336 if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
337 IN6_IS_ADDR_MC_INTFACELOCAL(a6)) && bufsiz >= IF_NAMESIZE) {
338 char *p = if_indextoname(ifindex, buf);
339 if (p) {
340 return(strlen(p));
341 }
342 }
343
344 /* last resort */
345 n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
346 if (n < 0 || n >= bufsiz)
347 return -1;
348 else
349 return n;
350}
351#endif /* INET6 */
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
38static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetbyaddr.c,v 1.4 1995/02/25 06:20:30 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
45 32
46extern int _net_stayopen; 33extern int _net_stayopen;
47 34
48struct netent * 35struct netent *
49getnetbyaddr(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
38static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetbyname.c,v 1.4 1995/02/25 06:20:31 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
45#include <string.h> 32#include <string.h>
46 33
47extern int _net_stayopen; 34extern int _net_stayopen;
48 35
49struct netent * 36struct netent *
50getnetbyname(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 }
64found: 50found:
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
index d4f0bedbf9..00fd543ec4 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.15 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 30.Dd $Mdocdate: May 31 2007 $
35.\"
36.Dd June 4, 1993
37.Dt GETNETENT 3 31.Dt GETNETENT 3
38.Os BSD 4.2 32.Os
39.Sh NAME 33.Sh NAME
40.Nm getnetent , 34.Nm getnetent ,
41.Nm getnetbyaddr , 35.Nm getnetbyaddr ,
@@ -46,31 +40,30 @@
46.Sh SYNOPSIS 40.Sh SYNOPSIS
47.Fd #include <netdb.h> 41.Fd #include <netdb.h>
48.Ft struct netent * 42.Ft struct netent *
49.Fn getnetent 43.Fn getnetent "void"
50.Ft struct netent * 44.Ft struct netent *
51.Fn getnetbyname "char *name" 45.Fn getnetbyname "const char *name"
52.Ft struct netent * 46.Ft struct netent *
53.Fn getnetbyaddr "long net" "int type" 47.Fn getnetbyaddr "in_addr_t net" "int type"
48.Ft void
54.Fn setnetent "int stayopen" 49.Fn setnetent "int stayopen"
55.Fn endnetent 50.Ft void
51.Fn endnetent "void"
56.Sh DESCRIPTION 52.Sh DESCRIPTION
57The 53The
58.Fn getnetent , 54.Fn getnetent ,
59.Fn getnetbyname , 55.Fn getnetbyname ,
60and 56and
61.Fn getnetbyaddr 57.Fn getnetbyaddr
62functions 58functions each return a pointer to an object with the following structure
63each return a pointer to an object with the 59containing the broken-out fields of a line in the network database,
64following structure
65containing the broken-out
66fields of a line in the network data base,
67.Pa /etc/networks . 60.Pa /etc/networks .
68.Bd -literal -offset indent 61.Bd -literal -offset indent
69struct netent { 62struct netent {
70 char *n_name; /* official name of net */ 63 char *n_name; /* official name of net */
71 char **n_aliases; /* alias list */ 64 char **n_aliases; /* alias list */
72 int n_addrtype; /* net number type */ 65 int n_addrtype; /* net number type */
73 unsigned long n_net; /* net number */ 66 in_addr_t n_net; /* net number */
74}; 67};
75.Ed 68.Ed
76.Pp 69.Pp
@@ -79,45 +72,42 @@ The members of this structure are:
79.It Fa n_name 72.It Fa n_name
80The official name of the network. 73The official name of the network.
81.It Fa n_aliases 74.It Fa n_aliases
82A zero terminated list of alternate names for the network. 75A null-terminated list of alternate names for the network.
83.It Fa n_addrtype 76.It Fa n_addrtype
84The type of the network number returned; currently only AF_INET. 77The type of the network number returned; currently only
78.Dv AF_INET .
85.It Fa n_net 79.It Fa n_net
86The network number. Network numbers are returned in machine byte 80The network number.
87order. 81Network numbers are returned in machine byte order.
88.El 82.El
89.Pp 83.Pp
90The 84The
91.Fn getnetent 85.Fn getnetent
92function 86function reads the next line of the file, opening the file if necessary.
93reads the next line of the file, opening the file if necessary.
94.Pp 87.Pp
95The 88The
96.Fn setnetent 89.Fn setnetent
97function 90function opens and rewinds the file.
98opens and rewinds the file. If the 91If the
99.Fa stayopen 92.Fa stayopen
100flag is non-zero, 93flag is non-zero,
101the net data base will not be closed after each call to 94the net database will not be closed after each call to
102.Fn getnetbyname 95.Fn getnetbyname
103or 96or
104.Fn getnetbyaddr . 97.Fn getnetbyaddr .
105.Pp 98.Pp
106The 99The
107.Fn endnetent 100.Fn endnetent
108function 101function closes the file.
109closes the file.
110.Pp 102.Pp
111The 103The
112.Fn getnetbyname 104.Fn getnetbyname
113function
114and 105and
115.Fn getnetbyaddr 106.Fn getnetbyaddr
116sequentially search from the beginning 107functions search the domain name server if the system is configured to use one.
117of the file until a matching 108If the search fails, or no name server is configured, they sequentially
118net name or 109search from the beginning of the file until a matching net name or
119net address and type is found, 110net address and type is found, or until
120or until
121.Dv EOF 111.Dv EOF
122is encountered. 112is encountered.
123Network numbers are supplied in host order. 113Network numbers are supplied in host order.
@@ -126,11 +116,11 @@ Network numbers are supplied in host order.
126.It Pa /etc/networks 116.It Pa /etc/networks
127.El 117.El
128.Sh DIAGNOSTICS 118.Sh DIAGNOSTICS
129Null pointer 119Null pointer (0) returned on
130(0) returned on
131.Dv EOF 120.Dv EOF
132or error. 121or error.
133.Sh SEE ALSO 122.Sh SEE ALSO
123.Xr resolver 3 ,
134.Xr networks 5 124.Xr networks 5
135.Sh HISTORY 125.Sh HISTORY
136The 126The
@@ -140,14 +130,11 @@ The
140.Fn setnetent , 130.Fn setnetent ,
141and 131and
142.Fn endnetent 132.Fn endnetent
143functions appeared in 133functions appeared in
144.Bx 4.2 . 134.Bx 4.2 .
145.Sh BUGS 135.Sh BUGS
146The data space used by 136The data space used by these functions is static; if future use
147these functions is static; if future use requires the data, it should be 137requires the data, it should be copied before any subsequent calls
148copied before any subsequent calls to these functions overwrite it. 138to these functions overwrite it.
149Only Internet network 139Only Internet network numbers are currently understood.
150numbers are currently understood. 140Expecting network numbers to fit in no more than 32 bits is naive.
151Expecting network numbers to fit
152in no more than 32 bits is probably
153naive.
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
index b4e16b8f5d..1bec6fb98c 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.12 2006/01/17 15:37:58 millert 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
38static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getnetent.c,v 1.4 1995/02/25 06:20:33 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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];
58int _net_stayopen; 45int _net_stayopen;
59 46
60void 47void
61setnetent(f) 48setnetent(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
71void 57void
72endnetent() 58endnetent(void)
73{ 59{
74 if (netf) { 60 if (netf) {
75 fclose(netf); 61 fclose(netf);
@@ -79,24 +65,29 @@ endnetent()
79} 65}
80 66
81struct netent * 67struct netent *
82getnetent() 68getnetent(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);
89again: 75again:
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;
@@ -116,8 +107,11 @@ again:
116 cp++; 107 cp++;
117 continue; 108 continue;
118 } 109 }
119 if (q < &net_aliases[MAXALIASES - 1]) 110 if (q < &net_aliases[MAXALIASES - 1]) {
120 *q++ = cp; 111 *q++ = cp;
112 if (strlen(cp) >= MAXHOSTNAMELEN-1)
113 cp[MAXHOSTNAMELEN-1] = '\0';
114 }
121 cp = strpbrk(cp, " \t"); 115 cp = strpbrk(cp, " \t");
122 if (cp != NULL) 116 if (cp != NULL)
123 *cp++ = '\0'; 117 *cp++ = '\0';
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000000..7b770f1ce7
--- /dev/null
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,384 @@
1/* $OpenBSD: getnetnamadr.c,v 1.26 2005/08/06 20:30:03 espie Exp $ */
2
3/*
4 * Copyright (c) 1997, Jason Downs. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
28 * Dep. Matematica Universidade de Coimbra, Portugal, Europe
29 *
30 * Permission to use, copy, modify, and distribute this software for any
31 * purpose with or without fee is hereby granted, provided that the above
32 * copyright notice and this permission notice appear in all copies.
33 */
34/*
35 * Copyright (c) 1983, 1993
36 * The Regents of the University of California. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE.
61 */
62
63#include <sys/types.h>
64#include <sys/param.h>
65#include <sys/socket.h>
66#include <netinet/in.h>
67#include <arpa/inet.h>
68#include <arpa/nameser.h>
69
70#include <stdio.h>
71#include <netdb.h>
72#include <resolv.h>
73#include <ctype.h>
74#include <errno.h>
75#include <string.h>
76#include <stdlib.h>
77
78#include "thread_private.h"
79
80extern int h_errno;
81
82struct netent *_getnetbyaddr(in_addr_t net, int type);
83struct netent *_getnetbyname(const char *name);
84
85int _hokchar(const char *);
86
87#define BYADDR 0
88#define BYNAME 1
89#define MAXALIASES 35
90
91#define MAXPACKET (64*1024)
92
93typedef union {
94 HEADER hdr;
95 u_char buf[MAXPACKET];
96} querybuf;
97
98typedef union {
99 long al;
100 char ac;
101} align;
102
103static struct netent *
104getnetanswer(querybuf *answer, int anslen, int net_i)
105{
106
107 HEADER *hp;
108 u_char *cp;
109 int n;
110 u_char *eom;
111 int type, class, ancount, qdcount, haveanswer, i, nchar;
112 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
113 char *in, *st, *pauxt, *bp, **ap, *ep;
114 char *paux1 = &aux1[0], *paux2 = &aux2[0];
115 static struct netent net_entry;
116 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
117
118 /*
119 * find first satisfactory answer
120 *
121 * answer --> +------------+ ( MESSAGE )
122 * | Header |
123 * +------------+
124 * | Question | the question for the name server
125 * +------------+
126 * | Answer | RRs answering the question
127 * +------------+
128 * | Authority | RRs pointing toward an authority
129 * | Additional | RRs holding additional information
130 * +------------+
131 */
132 eom = answer->buf + anslen;
133 hp = &answer->hdr;
134 ancount = ntohs(hp->ancount); /* #/records in the answer section */
135 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
136 bp = netbuf;
137 ep = netbuf + sizeof(netbuf);
138 cp = answer->buf + HFIXEDSZ;
139 if (!qdcount) {
140 if (hp->aa)
141 h_errno = HOST_NOT_FOUND;
142 else
143 h_errno = TRY_AGAIN;
144 return (NULL);
145 }
146 while (qdcount-- > 0) {
147 n = __dn_skipname(cp, eom);
148 if (n < 0 || (cp + n + QFIXEDSZ) > eom) {
149 h_errno = NO_RECOVERY;
150 return(NULL);
151 }
152 cp += n + QFIXEDSZ;
153 }
154 ap = net_aliases;
155 *ap = NULL;
156 net_entry.n_aliases = net_aliases;
157 haveanswer = 0;
158 while (--ancount >= 0 && cp < eom) {
159 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
160#ifdef USE_RESOLV_NAME_OK
161 if ((n < 0) || !res_dnok(bp))
162#else
163 if ((n < 0) || !_hokchar(bp))
164#endif
165 break;
166 cp += n;
167 ans[0] = '\0';
168 strlcpy(&ans[0], bp, sizeof ans);
169 GETSHORT(type, cp);
170 GETSHORT(class, cp);
171 cp += INT32SZ; /* TTL */
172 GETSHORT(n, cp);
173 if (class == C_IN && type == T_PTR) {
174 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
175#ifdef USE_RESOLV_NAME_OK
176 if ((n < 0) || !res_hnok(bp))
177#else
178 if ((n < 0) || !_hokchar(bp))
179#endif
180 {
181 cp += n;
182 return (NULL);
183 }
184 cp += n;
185 if ((ap + 2) < &net_aliases[MAXALIASES]) {
186 *ap++ = bp;
187 bp += strlen(bp) + 1;
188 net_entry.n_addrtype =
189 (class == C_IN) ? AF_INET : AF_UNSPEC;
190 haveanswer++;
191 }
192 }
193 }
194 if (haveanswer) {
195 *ap = NULL;
196 switch (net_i) {
197 case BYADDR:
198 net_entry.n_name = *net_entry.n_aliases;
199 net_entry.n_net = 0L;
200 break;
201 case BYNAME:
202 ap = net_entry.n_aliases;
203 next_alias:
204 in = *ap++;
205 if (in == NULL) {
206 h_errno = HOST_NOT_FOUND;
207 return (NULL);
208 }
209 net_entry.n_name = ans;
210 aux2[0] = '\0';
211 for (i = 0; i < 4; i++) {
212 for (st = in, nchar = 0;
213 isdigit((unsigned char)*st);
214 st++, nchar++)
215 ;
216 if (*st != '.' || nchar == 0 || nchar > 3)
217 goto next_alias;
218 if (i != 0)
219 nchar++;
220 strlcpy(paux1, in, nchar+1);
221 strlcat(paux1, paux2, MAXHOSTNAMELEN);
222 pauxt = paux2;
223 paux2 = paux1;
224 paux1 = pauxt;
225 in = ++st;
226 }
227 if (strcasecmp(in, "IN-ADDR.ARPA") != 0)
228 goto next_alias;
229 net_entry.n_net = inet_network(paux2);
230 break;
231 }
232 net_entry.n_aliases++;
233 return (&net_entry);
234 }
235 h_errno = TRY_AGAIN;
236 return (NULL);
237}
238
239struct netent *
240getnetbyaddr(in_addr_t net, int net_type)
241{
242 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
243 unsigned int netbr[4];
244 int nn, anslen;
245 querybuf *buf;
246 char qbuf[MAXDNAME];
247 in_addr_t net2;
248 struct netent *net_entry = NULL;
249 char lookups[MAXDNSLUS];
250 int i;
251
252 if (_res_init(0) == -1)
253 return(_getnetbyaddr(net, net_type));
254
255 bcopy(_resp->lookups, lookups, sizeof lookups);
256 if (lookups[0] == '\0')
257 strlcpy(lookups, "bf", sizeof lookups);
258
259 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
260 switch (lookups[i]) {
261#ifdef YP
262 case 'y':
263 /* There is no YP support. */
264 break;
265#endif /* YP */
266 case 'b':
267 if (net_type != AF_INET)
268 break; /* DNS only supports AF_INET? */
269
270 for (nn = 4, net2 = net; net2; net2 >>= 8)
271 netbr[--nn] = net2 & 0xff;
272 switch (nn) {
273 case 3: /* Class A */
274 snprintf(qbuf, sizeof(qbuf),
275 "0.0.0.%u.in-addr.arpa", netbr[3]);
276 break;
277 case 2: /* Class B */
278 snprintf(qbuf, sizeof(qbuf),
279 "0.0.%u.%u.in-addr.arpa",
280 netbr[3], netbr[2]);
281 break;
282 case 1: /* Class C */
283 snprintf(qbuf, sizeof(qbuf),
284 "0.%u.%u.%u.in-addr.arpa",
285 netbr[3], netbr[2], netbr[1]);
286 break;
287 case 0: /* Class D - E */
288 snprintf(qbuf, sizeof(qbuf),
289 "%u.%u.%u.%u.in-addr.arpa",
290 netbr[3], netbr[2], netbr[1], netbr[0]);
291 break;
292 }
293 buf = malloc(sizeof(*buf));
294 if (buf == NULL)
295 break;
296 anslen = res_query(qbuf, C_IN, T_PTR, buf->buf,
297 sizeof(buf->buf));
298 if (anslen < 0) {
299 free(buf);
300#ifdef DEBUG
301 if (_resp->options & RES_DEBUG)
302 printf("res_query failed\n");
303#endif
304 break;
305 }
306 net_entry = getnetanswer(buf, anslen, BYADDR);
307 free(buf);
308 if (net_entry != NULL) {
309 unsigned u_net = net; /* maybe net should be unsigned ? */
310
311 /* Strip trailing zeros */
312 while ((u_net & 0xff) == 0 && u_net != 0)
313 u_net >>= 8;
314 net_entry->n_net = u_net;
315 return (net_entry);
316 }
317 break;
318 case 'f':
319 net_entry = _getnetbyaddr(net, net_type);
320 if (net_entry != NULL)
321 return (net_entry);
322 }
323 }
324
325 /* Nothing matched. */
326 return (NULL);
327}
328
329struct netent *
330getnetbyname(const char *net)
331{
332 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
333 int anslen;
334 querybuf *buf;
335 char qbuf[MAXDNAME];
336 struct netent *net_entry = NULL;
337 char lookups[MAXDNSLUS];
338 int i;
339
340 if (_res_init(0) == -1)
341 return (_getnetbyname(net));
342
343 bcopy(_resp->lookups, lookups, sizeof lookups);
344 if (lookups[0] == '\0')
345 strlcpy(lookups, "bf", sizeof lookups);
346
347 for (i = 0; i < MAXDNSLUS && lookups[i]; i++) {
348 switch (lookups[i]) {
349#ifdef YP
350 case 'y':
351 /* There is no YP support. */
352 break;
353#endif /* YP */
354 case 'b':
355 strlcpy(qbuf, net, sizeof qbuf);
356 buf = malloc(sizeof(*buf));
357 if (buf == NULL)
358 break;
359 anslen = res_search(qbuf, C_IN, T_PTR, buf->buf,
360 sizeof(buf->buf));
361 if (anslen < 0) {
362 free(buf);
363#ifdef DEBUG
364 if (_resp->options & RES_DEBUG)
365 printf("res_query failed\n");
366#endif
367 break;
368 }
369 net_entry = getnetanswer(buf, anslen, BYNAME);
370 free(buf);
371 if (net_entry != NULL)
372 return (net_entry);
373 break;
374 case 'f':
375 net_entry = _getnetbyname(net);
376 if (net_entry != NULL)
377 return (net_entry);
378 break;
379 }
380 }
381
382 /* Nothing matched. */
383 return (NULL);
384}
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
38static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getproto.c,v 1.4 1995/02/25 06:20:33 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
32#include <stdio.h>
45 33
46extern int _proto_stayopen; 34int
35getprotobynumber_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
48struct protoent * 50struct protoent *
49getprotobynumber(proto) 51getprotobynumber(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..df4cd0c323 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.17 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,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: May 31 2007 $
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.Fd #include <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
57The 68The
58.Fn getprotoent , 69.Fn getprotoent ,
59.Fn getprotobyname , 70.Fn getprotobyname ,
60and 71and
61.Fn getprotobynumber 72.Fn getprotobynumber
62functions 73functions each return a pointer to an object with the following structure
63each return a pointer to an object with the 74containing the broken-out fields of a line in the network protocol database,
64following structure
65containing the broken-out
66fields of a line in the network protocol data base,
67.Pa /etc/protocols . 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
80The official name of the protocol. 88The official name of the protocol.
81.It Fa p_aliases 89.It Fa p_aliases
82A zero terminated list of alternate names for the protocol. 90A null-terminated list of alternate names for the protocol.
83.It Fa p_proto 91.It Fa p_proto
84The protocol number. 92The protocol number.
85.El 93.El
86.Pp 94.Pp
87The 95The
88.Fn getprotoent 96.Fn getprotoent
89function 97function reads the next line of the file, opening the file if necessary.
90reads the next line of the file, opening the file if necessary.
91.Pp 98.Pp
92The 99The
93.Fn setprotoent 100.Fn setprotoent
94function 101function opens and rewinds the file.
95opens and rewinds the file. If the 102If the
96.Fa stayopen 103.Fa stayopen
97flag is non-zero, 104flag is non-zero,
98the net data base will not be closed after each call to 105the protocol database will not be closed after each call to
99.Fn getprotobyname 106.Fn getprotobyname
100or 107or
101.Fn getprotobynumber . 108.Fn getprotobynumber .
102.Pp 109.Pp
103The 110The
104.Fn endprotoent 111.Fn endprotoent
105function 112function closes the file.
106closes the file.
107.Pp 113.Pp
108The 114The
109.Fn getprotobyname 115.Fn getprotobyname
110function
111and 116and
112.Fn getprotobynumber 117.Fn getprotobynumber
113sequentially search from the beginning 118functions sequentially search from the beginning of the file until a
114of the file until a matching 119matching protocol name or protocol number is found, or until
115protocol name or
116protocol number is found,
117or until
118.Dv EOF 120.Dv EOF
119is encountered. 121is encountered.
122.Pp
123The
124.Fn getprotoent_r ,
125.Fn getprotobyport_r ,
126.Fn getprotobyname_r ,
127.Fn setprotoent_r ,
128and
129.Fn endprotoent_r
130functions are reentrant versions of the above functions that take a
131pointer to a
132.Vt protoent_data
133structure which is used to store state information.
134The structure must be zero-filled before it is used
135and should be considered opaque for the sake of portability.
136.Pp
137The
138.Fn getprotoent_r ,
139.Fn getprotobyport_r ,
140and
141.Fn getprotobyname_r
142functions
143also take a pointer to a
144.Vt protoent
145structure which is used to store the results of the database lookup.
120.Sh RETURN VALUES 146.Sh RETURN VALUES
121Null pointer 147The
122(0) returned on 148.Fn getprotoent ,
123.Dv EOF 149.Fn getprotobyport ,
124or error. 150and
151.Fn getprotobyname
152functions return a pointer to a
153.Vt protoent
154structure on success or a null pointer if end-of-file
155is reached or an error occurs.
156.Pp
157The
158.Fn getprotoent_r ,
159.Fn getprotobyport_r ,
160and
161.Fn getprotobyname_r
162functions return 0 on success or \-1 if end-of-file
163is 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
171The
172.Fn getprotoent ,
173.Fn getprotobynumber ,
174.Fn getprotobyname ,
175.Fn setprotoent ,
176and
177.Fn endprotoent
178functions conform to
179.St -p1003.1-2004 .
180.Pp
181The
182.Fn getprotoent_r ,
183.Fn getprotobyport_r ,
184.Fn getprotobyname_r ,
185.Fn setprotoent_r ,
186and
187.Fn endprotoent_r
188functions are not currently standardized.
189This implementation follows the API used by HP, IBM, and Digital.
131.Sh HISTORY 190.Sh HISTORY
132The 191The
133.Fn getprotoent , 192.Fn getprotoent ,
@@ -136,11 +195,19 @@ The
136.Fn setprotoent , 195.Fn setprotoent ,
137and 196and
138.Fn endprotoent 197.Fn endprotoent
139functions appeared in 198functions appeared in
140.Bx 4.2 . 199.Bx 4.2 .
200.Pp
201The
202.Fn getprotoent_r ,
203.Fn getprotobyport_r ,
204.Fn getprotobyname_r ,
205.Fn setprotoent_r ,
206and
207.Fn endprotoent_r
208functions appeared in
209.Ox 3.7 .
141.Sh BUGS 210.Sh BUGS
142These functions use a static data space; 211The non-reentrant functions use a static data space; if the data is needed
143if the data is needed for future use, it should be 212for future use, it should be copied before any subsequent calls overwrite it.
144copied before any subsequent calls overwrite it. 213Only the Internet protocols are currently understood.
145Only the Internet
146protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
index 1179b9029b..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
38static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getprotoent.c,v 1.4 1995/02/25 06:20:35 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
53static FILE *protof = NULL;
54static char line[BUFSIZ+1];
55static struct protoent proto;
56static char *proto_aliases[MAXALIASES];
57int _proto_stayopen;
58
59void 41void
60setprotoent(f) 42setprotoent_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
70void 51void
71endprotoent() 52endprotoent_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
80struct protoent * 66int
81getprotoent() 67getprotoent_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);
88again: 76again:
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
144struct protoent_data _protoent_data; /* shared with getproto{,name}.c */
145
146void
147setprotoent(int f)
148{
149 setprotoent_r(f, &_protoent_data);
150}
151
152void
153endprotoent(void)
154{
155 endprotoent_r(&_protoent_data);
156}
157
158struct protoent *
159getprotoent(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
38static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getprotoname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
32#include <stdio.h>
45#include <string.h> 33#include <string.h>
46 34
47extern int _proto_stayopen; 35int
48 36getprotobyname_r(const char *name, struct protoent *pe,
49struct protoent * 37 struct protoent_data *pd)
50getprotobyname(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 }
64found: 50found:
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
58struct protoent *
59getprotobyname(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..121cb67fcc
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.3
@@ -0,0 +1,166 @@
1.\" $OpenBSD: getrrsetbyname.3,v 1.15 2007/05/31 19:19:30 jmc Exp $
2.\"
3.\" Copyright (C) 2000, 2001 Internet Software Consortium.
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
10.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
11.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
12.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
13.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd $Mdocdate: May 31 2007 $
19.Dt GETRRSETBYNAME 3
20.Os
21.Sh NAME
22.Nm freerrset ,
23.Nm getrrsetbyname
24.Nd retrieve DNS records
25.Sh SYNOPSIS
26.Fd #include <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
34gets a set of resource records associated with a
35.Fa hostname ,
36.Fa rdclass ,
37and
38.Fa rdtype .
39.Fa hostname
40is a pointer to a NUL-terminated string.
41The
42.Fa flags
43field is currently unused and must be zero.
44.Pp
45After a successful call to
46.Fn getrrsetbyname ,
47.Fa *res
48is a pointer to an
49.Li rrsetinfo
50structure, containing a list of one or more
51.Li rdatainfo
52structures containing resource records and potentially another list of
53.Li rdatainfo
54structures containing SIG resource records associated with those records.
55The members
56.Li rri_rdclass
57and
58.Li rri_rdtype
59are copied from the parameters.
60.Li rri_ttl
61and
62.Li rri_name
63are properties of the obtained rrset.
64The resource records contained in
65.Li rri_rdatas
66and
67.Li rri_sigs
68are in uncompressed DNS wire format.
69Properties of the rdataset are represented in the
70.Li rri_flags
71bitfield.
72If the
73.Dv RRSET_VALIDATED
74bit is set, the data has been DNSSEC
75validated and the signatures verified.
76.Pp
77The following structures are used:
78.Bd -literal -offset indent
79struct rdatainfo {
80 unsigned int rdi_length; /* length of data */
81 unsigned char *rdi_data; /* record data */
82};
83
84struct 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
97All of the information returned by
98.Fn getrrsetbyname
99is dynamically allocated: the
100.Li rrsetinfo
101and
102.Li rdatainfo
103structures,
104and the canonical host name strings pointed to by the
105.Li rrsetinfo
106structure.
107Memory allocated for the dynamically allocated structures created by
108a successful call to
109.Fn getrrsetbyname
110is released by
111.Fn freerrset .
112.Li rrset
113is a pointer to a
114.Li struct rrsetinfo
115created by a call to
116.Fn getrrsetbyname .
117.Pp
118If the EDNS0 option is activated in
119.Xr resolv.conf 5 ,
120.Fn getrrsetbyname
121will request DNSSEC authentication using the EDNS0 DNSSEC OK (DO) bit.
122.Sh RETURN VALUES
123.Fn getrrsetbyname
124returns zero on success, and one of the following error
125codes if an error occurred:
126.Pp
127.Bl -tag -width ERRSET_NOMEMORY
128.It Bq Er ERRSET_NONAME
129The name does not exist.
130.It Bq Er ERRSET_NODATA
131The name exists, but does not have data of the desired type.
132.It Bq Er ERRSET_NOMEMORY
133Memory could not be allocated.
134.It Bq Er ERRSET_INVAL
135A parameter is invalid.
136.It Bq Er ERRSET_FAIL
137Other failure.
138.El
139.Sh SEE ALSO
140.Xr resolver 3 ,
141.Xr resolv.conf 5 ,
142.Xr named 8
143.Sh HISTORY
144.Fn getrrsetbyname
145first appeared in
146.Ox 3.0 .
147The API first appeared in ISC BIND version 9.
148.Sh AUTHORS
149.An Jakob Schlyter Aq jakob@openbsd.org
150.Sh CAVEATS
151The
152.Dv RRSET_VALIDATED
153flag in
154.Li rri_flags
155is set if the AD (authenticated data) bit in the DNS answer is
156set.
157This flag
158.Em should not
159be trusted unless the transport between the nameserver and the resolver
160is secure (e.g. IPsec, trusted network, loopback communication).
161.Sh BUGS
162The data in
163.Li *rdi_data
164should be returned in uncompressed wire format.
165Currently, the data is in compressed format and the caller can't
166uncompress since it doesn't have the full message.
diff --git a/src/lib/libc/net/getrrsetbyname.c b/src/lib/libc/net/getrrsetbyname.c
new file mode 100644
index 0000000000..89aa592ba0
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.c
@@ -0,0 +1,514 @@
1/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */
2
3/*
4 * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Portions Copyright (c) 1999-2001 Internet Software Consortium.
31 *
32 * Permission to use, copy, modify, and distribute this software for any
33 * purpose with or without fee is hereby granted, provided that the above
34 * copyright notice and this permission notice appear in all copies.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
37 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
39 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
40 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
41 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
42 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
43 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46#include <sys/types.h>
47#include <netinet/in.h>
48#include <arpa/nameser.h>
49#include <netdb.h>
50#include <resolv.h>
51#include <stdlib.h>
52#include <string.h>
53
54#include "thread_private.h"
55
56#define ANSWER_BUFFER_SIZE 1024*64
57
58struct dns_query {
59 char *name;
60 u_int16_t type;
61 u_int16_t class;
62 struct dns_query *next;
63};
64
65struct dns_rr {
66 char *name;
67 u_int16_t type;
68 u_int16_t class;
69 u_int16_t ttl;
70 u_int16_t size;
71 void *rdata;
72 struct dns_rr *next;
73};
74
75struct dns_response {
76 HEADER header;
77 struct dns_query *query;
78 struct dns_rr *answer;
79 struct dns_rr *authority;
80 struct dns_rr *additional;
81};
82
83static struct dns_response *parse_dns_response(const u_char *, int);
84static struct dns_query *parse_dns_qsection(const u_char *, int,
85 const u_char **, int);
86static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
87 int);
88
89static void free_dns_query(struct dns_query *);
90static void free_dns_rr(struct dns_rr *);
91static void free_dns_response(struct dns_response *);
92
93static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
94
95int
96getrrsetbyname(const char *hostname, unsigned int rdclass,
97 unsigned int rdtype, unsigned int flags,
98 struct rrsetinfo **res)
99{
100 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
101 int result;
102 struct rrsetinfo *rrset = NULL;
103 struct dns_response *response = NULL;
104 struct dns_rr *rr;
105 struct rdatainfo *rdata;
106 int length;
107 unsigned int index_ans, index_sig;
108 u_char answer[ANSWER_BUFFER_SIZE];
109
110 /* check for invalid class and type */
111 if (rdclass > 0xffff || rdtype > 0xffff) {
112 result = ERRSET_INVAL;
113 goto fail;
114 }
115
116 /* don't allow queries of class or type ANY */
117 if (rdclass == 0xff || rdtype == 0xff) {
118 result = ERRSET_INVAL;
119 goto fail;
120 }
121
122 /* don't allow flags yet, unimplemented */
123 if (flags) {
124 result = ERRSET_INVAL;
125 goto fail;
126 }
127
128 /* initialize resolver */
129 if (_res_init(0) == -1) {
130 result = ERRSET_FAIL;
131 goto fail;
132 }
133
134#ifdef DEBUG
135 _resp->options |= RES_DEBUG;
136#endif /* DEBUG */
137
138#ifdef RES_USE_DNSSEC
139 /* turn on DNSSEC if EDNS0 is configured */
140 if (_resp->options & RES_USE_EDNS0)
141 _resp->options |= RES_USE_DNSSEC;
142#endif /* RES_USE_DNSEC */
143
144 /* make query */
145 length = res_query(hostname, (signed int) rdclass, (signed int) rdtype,
146 answer, sizeof(answer));
147 if (length < 0) {
148 switch(h_errno) {
149 case HOST_NOT_FOUND:
150 result = ERRSET_NONAME;
151 goto fail;
152 case NO_DATA:
153 result = ERRSET_NODATA;
154 goto fail;
155 default:
156 result = ERRSET_FAIL;
157 goto fail;
158 }
159 }
160
161 /* parse result */
162 response = parse_dns_response(answer, length);
163 if (response == NULL) {
164 result = ERRSET_FAIL;
165 goto fail;
166 }
167
168 if (response->header.qdcount != 1) {
169 result = ERRSET_FAIL;
170 goto fail;
171 }
172
173 /* initialize rrset */
174 rrset = calloc(1, sizeof(struct rrsetinfo));
175 if (rrset == NULL) {
176 result = ERRSET_NOMEMORY;
177 goto fail;
178 }
179 rrset->rri_rdclass = response->query->class;
180 rrset->rri_rdtype = response->query->type;
181 rrset->rri_ttl = response->answer->ttl;
182 rrset->rri_nrdatas = response->header.ancount;
183
184 /* check for authenticated data */
185 if (response->header.ad == 1)
186 rrset->rri_flags |= RRSET_VALIDATED;
187
188 /* copy name from answer section */
189 rrset->rri_name = strdup(response->answer->name);
190 if (rrset->rri_name == NULL) {
191 result = ERRSET_NOMEMORY;
192 goto fail;
193 }
194
195 /* count answers */
196 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
197 rrset->rri_rdtype);
198 rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
199 T_RRSIG);
200
201 /* allocate memory for answers */
202 rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
203 sizeof(struct rdatainfo));
204 if (rrset->rri_rdatas == NULL) {
205 result = ERRSET_NOMEMORY;
206 goto fail;
207 }
208
209 /* allocate memory for signatures */
210 rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
211 if (rrset->rri_sigs == NULL) {
212 result = ERRSET_NOMEMORY;
213 goto fail;
214 }
215
216 /* copy answers & signatures */
217 for (rr = response->answer, index_ans = 0, index_sig = 0;
218 rr; rr = rr->next) {
219
220 rdata = NULL;
221
222 if (rr->class == rrset->rri_rdclass &&
223 rr->type == rrset->rri_rdtype)
224 rdata = &rrset->rri_rdatas[index_ans++];
225
226 if (rr->class == rrset->rri_rdclass &&
227 rr->type == T_RRSIG)
228 rdata = &rrset->rri_sigs[index_sig++];
229
230 if (rdata) {
231 rdata->rdi_length = rr->size;
232 rdata->rdi_data = malloc(rr->size);
233
234 if (rdata->rdi_data == NULL) {
235 result = ERRSET_NOMEMORY;
236 goto fail;
237 }
238 memcpy(rdata->rdi_data, rr->rdata, rr->size);
239 }
240 }
241 free_dns_response(response);
242
243 *res = rrset;
244 return (ERRSET_SUCCESS);
245
246fail:
247 if (rrset != NULL)
248 freerrset(rrset);
249 if (response != NULL)
250 free_dns_response(response);
251 return (result);
252}
253
254void
255freerrset(struct rrsetinfo *rrset)
256{
257 u_int16_t i;
258
259 if (rrset == NULL)
260 return;
261
262 if (rrset->rri_rdatas) {
263 for (i = 0; i < rrset->rri_nrdatas; i++) {
264 if (rrset->rri_rdatas[i].rdi_data == NULL)
265 break;
266 free(rrset->rri_rdatas[i].rdi_data);
267 }
268 free(rrset->rri_rdatas);
269 }
270
271 if (rrset->rri_sigs) {
272 for (i = 0; i < rrset->rri_nsigs; i++) {
273 if (rrset->rri_sigs[i].rdi_data == NULL)
274 break;
275 free(rrset->rri_sigs[i].rdi_data);
276 }
277 free(rrset->rri_sigs);
278 }
279
280 if (rrset->rri_name)
281 free(rrset->rri_name);
282 free(rrset);
283}
284
285/*
286 * DNS response parsing routines
287 */
288static struct dns_response *
289parse_dns_response(const u_char *answer, int size)
290{
291 struct dns_response *resp;
292 const u_char *cp;
293
294 /* allocate memory for the response */
295 resp = calloc(1, sizeof(*resp));
296 if (resp == NULL)
297 return (NULL);
298
299 /* initialize current pointer */
300 cp = answer;
301
302 /* copy header */
303 memcpy(&resp->header, cp, HFIXEDSZ);
304 cp += HFIXEDSZ;
305
306 /* fix header byte order */
307 resp->header.qdcount = ntohs(resp->header.qdcount);
308 resp->header.ancount = ntohs(resp->header.ancount);
309 resp->header.nscount = ntohs(resp->header.nscount);
310 resp->header.arcount = ntohs(resp->header.arcount);
311
312 /* there must be at least one query */
313 if (resp->header.qdcount < 1) {
314 free_dns_response(resp);
315 return (NULL);
316 }
317
318 /* parse query section */
319 resp->query = parse_dns_qsection(answer, size, &cp,
320 resp->header.qdcount);
321 if (resp->header.qdcount && resp->query == NULL) {
322 free_dns_response(resp);
323 return (NULL);
324 }
325
326 /* parse answer section */
327 resp->answer = parse_dns_rrsection(answer, size, &cp,
328 resp->header.ancount);
329 if (resp->header.ancount && resp->answer == NULL) {
330 free_dns_response(resp);
331 return (NULL);
332 }
333
334 /* parse authority section */
335 resp->authority = parse_dns_rrsection(answer, size, &cp,
336 resp->header.nscount);
337 if (resp->header.nscount && resp->authority == NULL) {
338 free_dns_response(resp);
339 return (NULL);
340 }
341
342 /* parse additional section */
343 resp->additional = parse_dns_rrsection(answer, size, &cp,
344 resp->header.arcount);
345 if (resp->header.arcount && resp->additional == NULL) {
346 free_dns_response(resp);
347 return (NULL);
348 }
349
350 return (resp);
351}
352
353static struct dns_query *
354parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
355{
356 struct dns_query *head, *curr, *prev;
357 int i, length;
358 char name[MAXDNAME];
359
360 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
361
362 /* allocate and initialize struct */
363 curr = calloc(1, sizeof(struct dns_query));
364 if (curr == NULL) {
365 free_dns_query(head);
366 return (NULL);
367 }
368 if (head == NULL)
369 head = curr;
370 if (prev != NULL)
371 prev->next = curr;
372
373 /* name */
374 length = dn_expand(answer, answer + size, *cp, name,
375 sizeof(name));
376 if (length < 0) {
377 free_dns_query(head);
378 return (NULL);
379 }
380 curr->name = strdup(name);
381 if (curr->name == NULL) {
382 free_dns_query(head);
383 return (NULL);
384 }
385 *cp += length;
386
387 /* type */
388 curr->type = _getshort(*cp);
389 *cp += INT16SZ;
390
391 /* class */
392 curr->class = _getshort(*cp);
393 *cp += INT16SZ;
394 }
395
396 return (head);
397}
398
399static struct dns_rr *
400parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
401 int count)
402{
403 struct dns_rr *head, *curr, *prev;
404 int i, length;
405 char name[MAXDNAME];
406
407 for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
408
409 /* allocate and initialize struct */
410 curr = calloc(1, sizeof(struct dns_rr));
411 if (curr == NULL) {
412 free_dns_rr(head);
413 return (NULL);
414 }
415 if (head == NULL)
416 head = curr;
417 if (prev != NULL)
418 prev->next = curr;
419
420 /* name */
421 length = dn_expand(answer, answer + size, *cp, name,
422 sizeof(name));
423 if (length < 0) {
424 free_dns_rr(head);
425 return (NULL);
426 }
427 curr->name = strdup(name);
428 if (curr->name == NULL) {
429 free_dns_rr(head);
430 return (NULL);
431 }
432 *cp += length;
433
434 /* type */
435 curr->type = _getshort(*cp);
436 *cp += INT16SZ;
437
438 /* class */
439 curr->class = _getshort(*cp);
440 *cp += INT16SZ;
441
442 /* ttl */
443 curr->ttl = _getlong(*cp);
444 *cp += INT32SZ;
445
446 /* rdata size */
447 curr->size = _getshort(*cp);
448 *cp += INT16SZ;
449
450 /* rdata itself */
451 curr->rdata = malloc(curr->size);
452 if (curr->rdata == NULL) {
453 free_dns_rr(head);
454 return (NULL);
455 }
456 memcpy(curr->rdata, *cp, curr->size);
457 *cp += curr->size;
458 }
459
460 return (head);
461}
462
463static void
464free_dns_query(struct dns_query *p)
465{
466 if (p == NULL)
467 return;
468
469 if (p->name)
470 free(p->name);
471 free_dns_query(p->next);
472 free(p);
473}
474
475static void
476free_dns_rr(struct dns_rr *p)
477{
478 if (p == NULL)
479 return;
480
481 if (p->name)
482 free(p->name);
483 if (p->rdata)
484 free(p->rdata);
485 free_dns_rr(p->next);
486 free(p);
487}
488
489static void
490free_dns_response(struct dns_response *p)
491{
492 if (p == NULL)
493 return;
494
495 free_dns_query(p->query);
496 free_dns_rr(p->answer);
497 free_dns_rr(p->authority);
498 free_dns_rr(p->additional);
499 free(p);
500}
501
502static int
503count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
504{
505 int n = 0;
506
507 while(p) {
508 if (p->class == class && p->type == type)
509 n++;
510 p = p->next;
511 }
512
513 return (n);
514}
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
38static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservbyname.c,v 1.4 1995/02/25 06:20:36 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
32#include <stdio.h>
45#include <string.h> 33#include <string.h>
46 34
47extern int _serv_stayopen; 35int
48 36getservbyname_r(const char *name, const char *proto, struct servent *se,
49struct servent * 37 struct servent_data *sd)
50getservbyname(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;
64gotname: 50gotname:
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
61struct servent *
62getservbyname(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
38static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservbyport.c,v 1.4 1995/02/25 06:20:37 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <netdb.h> 31#include <netdb.h>
32#include <stdio.h>
45#include <string.h> 33#include <string.h>
46 34
47extern int _serv_stayopen; 35int
48 36getservbyport_r(int port, const char *proto, struct servent *se,
49struct servent * 37 struct servent_data *sd)
50getservbyport(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
55struct servent *
56getservbyport(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..7888b5f1b8 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.20 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,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: May 31 2007 $
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.Fd #include <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
59The 68The
60.Fn getservent , 69.Fn getservent ,
61.Fn getservbyname , 70.Fn getservbyname ,
62and 71and
63.Fn getservbyport 72.Fn getservbyport
64functions 73functions each return a pointer to an object with the following structure
65each return a pointer to an object with the 74containing the broken-out fields of a line in the network services database,
66following structure
67containing the broken-out
68fields of a line in the network services data base,
69.Pa /etc/services . 75.Pa /etc/services .
70.Bd -literal -offset indent 76.Bd -literal -offset indent
71struct servent { 77struct servent {
@@ -81,64 +87,113 @@ The members of this structure are:
81.It Fa s_name 87.It Fa s_name
82The official name of the service. 88The official name of the service.
83.It Fa s_aliases 89.It Fa s_aliases
84A zero terminated list of alternate names for the service. 90A null-terminated list of alternate names for the service.
85.It Fa s_port 91.It Fa s_port
86The port number at which the service resides. 92The port number at which the service resides.
87Port numbers are returned in network byte order. 93Port numbers are returned in network byte order.
88.It Fa s_proto 94.It Fa s_proto
89The name of the protocol to use when contacting the 95The name of the protocol to use when contacting the service.
90service.
91.El 96.El
92.Pp 97.Pp
93The 98The
94.Fn getservent 99.Fn getservent
95function 100function reads the next line of the file, opening the file if necessary.
96reads the next line of the file, opening the file if necessary.
97.Pp 101.Pp
98The 102The
99.Fn setservent 103.Fn setservent
100function 104function opens and rewinds the file.
101opens and rewinds the file. If the 105If the
102.Fa stayopen 106.Fa stayopen
103flag is non-zero, 107flag is non-zero,
104the net data base will not be closed after each call to 108the services database will not be closed after each call to
105.Fn getservbyname 109.Fn getservbyname
106or 110or
107.Fn getservbyport . 111.Fn getservbyport .
108.Pp 112.Pp
109The 113The
110.Fn endservent 114.Fn endservent
111function 115function closes the file.
112closes the file.
113.Pp 116.Pp
114The 117The
115.Fn getservbyname 118.Fn getservbyname
116and 119and
117.Fn getservbyport 120.Fn getservbyport
118functions 121functions sequentially search from the beginning of the file until a
119sequentially search from the beginning 122matching protocol name or port number (specified in network byte order)
120of the file until a matching 123is found, or until
121protocol name or
122port number is found,
123or until
124.Dv EOF 124.Dv EOF
125is encountered. 125is encountered.
126If a protocol name is also supplied (non- 126If a protocol name is also supplied (non-null),
127.Dv NULL ) ,
128searches must also match the protocol. 127searches must also match the protocol.
129.ne 1i 128.Pp
129The
130.Fn getservent_r ,
131.Fn getservbyport_r ,
132.Fn getservbyname_r ,
133.Fn setservent_r ,
134and
135.Fn endservent_r
136functions are reentrant versions of the above functions that take a
137pointer to a
138.Fa servent_data
139structure which is used to store state information.
140The structure must be zero-filled before it is used
141and should be considered opaque for the sake of portability.
142.Pp
143The
144.Fn getservent_r ,
145.Fn getservbyport_r ,
146and
147.Fn getservbyname_r
148functions
149also take a pointer to a
150.Fa servent
151structure which is used to store the results of the database lookup.
152.Sh RETURN VALUES
153The
154.Fn getservent ,
155.Fn getservbyport ,
156and
157.Fn getservbyname
158functions return a pointer to a
159.Fa servent
160structure on success or a null pointer if end-of-file
161is reached or an error occurs.
162.Pp
163The
164.Fn getservent_r ,
165.Fn getservbyport_r ,
166and
167.Fn getservbyname_r
168functions return 0 on success or \-1 if end-of-file
169is 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
135Null pointer
136(0) returned on
137.Dv EOF
138or 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
178The
179.Fn getservent ,
180.Fn getservbynumber ,
181.Fn getservbyname ,
182.Fn setservent ,
183and
184.Fn endservent
185functions conform to
186.St -p1003.1-2004 .
187.Pp
188The
189.Fn getservent_r ,
190.Fn getservbyport_r ,
191.Fn getservbyname_r ,
192.Fn setservent_r ,
193and
194.Fn endservent_r
195functions are not currently standardized.
196This implementation follows the API used by HP, IBM, and Digital.
142.Sh HISTORY 197.Sh HISTORY
143The 198The
144.Fn getservent , 199.Fn getservent ,
@@ -147,11 +202,19 @@ The
147.Fn setservent , 202.Fn setservent ,
148and 203and
149.Fn endservent 204.Fn endservent
150functions appeared in 205functions appeared in
151.Bx 4.2 . 206.Bx 4.2 .
207.Pp
208The
209.Fn getservent_r ,
210.Fn getservbyport_r ,
211.Fn getservbyname_r ,
212.Fn setservent_r ,
213and
214.Fn endservent_r
215functions appeared in
216.Ox 3.7 .
152.Sh BUGS 217.Sh BUGS
153These functions use static data storage; 218The non-reentrant functions use static data storage; if the data is needed
154if the data is needed for future use, it should be 219for future use, it should be copied before any subsequent calls overwrite it.
155copied before any subsequent calls overwrite it. 220Expecting port numbers to fit in a 32-bit quantity is probably naive.
156Expecting port numbers to fit in a 32 bit
157quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
index 316891450e..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
38static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: getservent.c,v 1.4 1995/02/25 06:20:38 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
53static FILE *servf = NULL;
54static char line[BUFSIZ+1];
55static struct servent serv;
56static char *serv_aliases[MAXALIASES];
57int _serv_stayopen;
58
59void 41void
60setservent(f) 42setservent_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
70void 51void
71endservent() 52endservent_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
80struct servent * 66int
81getservent() 67getservent_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);
88again: 76again:
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
146struct servent_data _servent_data; /* shared with getservby{name,port}.c */
147
148void
149setservent(int f)
150{
151 setservent_r(f, &_servent_data);
152}
153
154void
155endservent(void)
156{
157 endservent_r(&_servent_data);
158}
159
160struct servent *
161getservent(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
58static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: herror.c,v 4.9.1.1 1993/05/02 23:14:35 vixie Rel ";
60#else
61static 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
71char *h_errlist[] = { 61const 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};
78int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; 68const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
79 69
80extern int h_errno; 70extern 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 */
86void 76void
87herror(s) 77herror(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
110char * 98const char *
111hstrerror(err) 99hstrerror(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)
9static 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
17unsigned long 12u_int32_t
18htonl(x) 13htonl(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)
9static 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
17unsigned short 12u_int16_t
18htons(x) 13htons(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..8ffc35a5fa
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.3
@@ -0,0 +1,144 @@
1.\" $OpenBSD: if_indextoname.3,v 1.11 2007/05/31 19:19:30 jmc Exp $
2.\" Copyright (c) 1983, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. Neither the name of the University nor the names of its contributors
14.\" may be used to endorse or promote products derived from this software
15.\" without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
30.\"
31.Dd $Mdocdate: May 31 2007 $
32.Dt IF_NAMETOINDEX 3
33.Os
34.Sh NAME
35.Nm if_nametoindex ,
36.Nm if_indextoname ,
37.Nm if_nameindex ,
38.Nm if_freenameindex
39.Nd convert interface index to name, and vice versa
40.Sh SYNOPSIS
41.Fd #include <sys/types.h>
42.Fd #include <sys/socket.h>
43.Fd #include <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
53These functions map interface indexes to interface names (such as
54.Dq lo0 ) ,
55and vice versa.
56.Pp
57The
58.Fn if_nametoindex
59function converts an interface name specified by the
60.Fa ifname
61argument to an interface index (positive integer value).
62If the specified interface does not exist, 0 will be returned.
63.Pp
64.Fn if_indextoname
65converts an interface index specified by the
66.Fa ifindex
67argument to an interface name.
68The
69.Fa ifname
70argument must point to a buffer of at least
71.Dv IF_NAMESIZE
72bytes into which the interface name corresponding to the specified index is
73returned.
74.Pf ( Dv IF_NAMESIZE
75is also defined in
76.Aq Pa net/if.h
77and its value includes a terminating NUL byte at the end of the
78interface name.)
79This pointer is also the return value of the function.
80If there is no interface corresponding to the specified index,
81.Dv NULL
82is returned.
83.Pp
84.Fn if_nameindex
85returns an array of
86.Vt if_nameindex
87structures.
88.Vt if_nameindex
89is also defined in
90.Aq Pa net/if.h ,
91and is as follows:
92.Bd -literal -offset indent
93struct if_nameindex {
94 unsigned int if_index; /* 1, 2, ... */
95 char *if_name; /* NUL-terminated name */
96};
97.Ed
98.Pp
99The end of the array of structures is indicated by a structure with
100an
101.Fa if_index
102of 0 and an
103.Fa if_name
104of
105.Dv NULL .
106The function returns a null pointer on error.
107The memory used for this array of structures along with the interface
108names pointed to by the
109.Fa if_name
110members is obtained dynamically.
111This memory is freed by the
112.Fn if_freenameindex
113function.
114.Pp
115.Fn if_freenameindex
116takes a pointer that was returned by
117.Fn if_nameindex
118as argument
119.Pq Fa ptr ,
120and it reclaims the region allocated.
121.Sh DIAGNOSTICS
122.Fn if_nametoindex
123returns 0 on error, positive integer on success.
124.Fn if_indextoname
125and
126.Fn if_nameindex
127return
128.Dv NULL
129on errors.
130.Sh SEE ALSO
131.Xr getifaddrs 3 ,
132.Xr networking 4
133.Rs
134.%A R. Gilligan
135.%A S. Thomson
136.%A J. Bound
137.%A W. Stevens
138.%T Basic Socket Interface Extensions for IPv6
139.%R RFC 2553
140.%D March 1999
141.Re
142.Sh STANDARDS
143These functions are defined in ``Basic Socket Interface Extensions for IPv6''
144.Pq RFC 2533 .
diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c
new file mode 100644
index 0000000000..f99e52e387
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.c
@@ -0,0 +1,86 @@
1/* $OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2533:
40 *
41 * The second function maps an interface index into its corresponding
42 * name.
43 *
44 * #include <net/if.h>
45 *
46 * char *if_indextoname(unsigned int ifindex, char *ifname);
47 *
48 * The ifname argument must point to a buffer of at least IF_NAMESIZE
49 * bytes into which the interface name corresponding to the specified
50 * index is returned. (IF_NAMESIZE is also defined in <net/if.h> and
51 * its value includes a terminating null byte at the end of the
52 * interface name.) This pointer is also the return value of the
53 * function. If there is no interface corresponding to the specified
54 * index, NULL is returned, and errno is set to ENXIO, if there was a
55 * system error (such as running out of memory), if_indextoname returns
56 * NULL and errno would be set to the proper value (e.g., ENOMEM).
57 */
58
59char *
60if_indextoname(unsigned int ifindex, char *ifname)
61{
62 struct ifaddrs *ifaddrs, *ifa;
63 int error = 0;
64
65 if (getifaddrs(&ifaddrs) < 0)
66 return(NULL); /* getifaddrs properly set errno */
67
68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
69 if (ifa->ifa_addr &&
70 ifa->ifa_addr->sa_family == AF_LINK &&
71 ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index)
72 break;
73 }
74
75 if (ifa == NULL) {
76 error = ENXIO;
77 ifname = NULL;
78 }
79 else
80 strlcpy(ifname, ifa->ifa_name, IFNAMSIZ);
81
82 freeifaddrs(ifaddrs);
83
84 errno = error;
85 return(ifname);
86}
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
new file mode 100644
index 0000000000..3675a2a450
--- /dev/null
+++ b/src/lib/libc/net/if_nameindex.c
@@ -0,0 +1,140 @@
1/* $OpenBSD: if_nameindex.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36
37/*
38 * From RFC 2553:
39 *
40 * 4.3 Return All Interface Names and Indexes
41 *
42 * The if_nameindex structure holds the information about a single
43 * interface and is defined as a result of including the <net/if.h>
44 * header.
45 *
46 * struct if_nameindex {
47 * unsigned int if_index;
48 * char *if_name;
49 * };
50 *
51 * The final function returns an array of if_nameindex structures, one
52 * structure per interface.
53 *
54 * struct if_nameindex *if_nameindex(void);
55 *
56 * The end of the array of structures is indicated by a structure with
57 * an if_index of 0 and an if_name of NULL. The function returns a NULL
58 * pointer upon an error, and would set errno to the appropriate value.
59 *
60 * The memory used for this array of structures along with the interface
61 * names pointed to by the if_name members is obtained dynamically.
62 * This memory is freed by the next function.
63 *
64 * 4.4. Free Memory
65 *
66 * The following function frees the dynamic memory that was allocated by
67 * if_nameindex().
68 *
69 * #include <net/if.h>
70 *
71 * void if_freenameindex(struct if_nameindex *ptr);
72 *
73 * The argument to this function must be a pointer that was returned by
74 * if_nameindex().
75 */
76
77struct if_nameindex *
78if_nameindex(void)
79{
80 struct ifaddrs *ifaddrs, *ifa;
81 unsigned int ni;
82 size_t nbytes;
83 struct if_nameindex *ifni, *ifni2;
84 char *cp;
85
86 if (getifaddrs(&ifaddrs) < 0)
87 return(NULL);
88
89 /*
90 * First, find out how many interfaces there are, and how
91 * much space we need for the string names.
92 */
93 ni = 0;
94 nbytes = 0;
95 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
96 if (ifa->ifa_addr &&
97 ifa->ifa_addr->sa_family == AF_LINK) {
98 nbytes += strlen(ifa->ifa_name) + 1;
99 ni++;
100 }
101 }
102
103 /*
104 * Next, allocate a chunk of memory, use the first part
105 * for the array of structures, and the last part for
106 * the strings.
107 */
108 cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
109 ifni = (struct if_nameindex *)cp;
110 if (ifni == NULL)
111 goto out;
112 cp += (ni + 1) * sizeof(struct if_nameindex);
113
114 /*
115 * Now just loop through the list of interfaces again,
116 * filling in the if_nameindex array and making copies
117 * of all the strings.
118 */
119 ifni2 = ifni;
120 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
121 if (ifa->ifa_addr &&
122 ifa->ifa_addr->sa_family == AF_LINK) {
123 ifni2->if_index =
124 ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
125 ifni2->if_name = cp;
126 nbytes = strlen(ifa->ifa_name) + 1;
127 memcpy(cp, ifa->ifa_name, nbytes);
128 ifni2++;
129 cp += nbytes;
130 }
131 }
132 /*
133 * Finally, don't forget to terminate the array.
134 */
135 ifni2->if_index = 0;
136 ifni2->if_name = NULL;
137out:
138 freeifaddrs(ifaddrs);
139 return(ifni);
140}
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c
new file mode 100644
index 0000000000..8bd792b949
--- /dev/null
+++ b/src/lib/libc/net/if_nametoindex.c
@@ -0,0 +1,81 @@
1/* $OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nametoindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <net/if_dl.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2553:
40 *
41 * 4.1 Name-to-Index
42 *
43 *
44 * The first function maps an interface name into its corresponding
45 * index.
46 *
47 * #include <net/if.h>
48 *
49 * unsigned int if_nametoindex(const char *ifname);
50 *
51 * If the specified interface name does not exist, the return value is
52 * 0, and errno is set to ENXIO. If there was a system error (such as
53 * running out of memory), the return value is 0 and errno is set to the
54 * proper value (e.g., ENOMEM).
55 */
56
57unsigned int
58if_nametoindex(const char *ifname)
59{
60 struct ifaddrs *ifaddrs, *ifa;
61 unsigned int ni;
62
63 if (getifaddrs(&ifaddrs) < 0)
64 return(0);
65
66 ni = 0;
67
68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
69 if (ifa->ifa_addr &&
70 ifa->ifa_addr->sa_family == AF_LINK &&
71 strcmp(ifa->ifa_name, ifname) == 0) {
72 ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
73 break;
74 }
75 }
76
77 freeifaddrs(ifaddrs);
78 if (!ni)
79 errno = ENXIO;
80 return(ni);
81}
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3
index 49bac97e96..c650df360b 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.21 2007/06/12 16:50:06 jmc Exp $
2.\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $
2.\" 3.\"
3.\" Copyright (c) 1983, 1990, 1991, 1993 4.\" Copyright (c) 1983, 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 5.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +12,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 16.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 17.\" without specific prior written permission.
21.\" 18.\"
@@ -33,52 +30,74 @@
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 12 2007 $
37.Dt INET 3 34.Dt INET 3
38.Os BSD 4.2 35.Os
39.Sh NAME 36.Sh NAME
40.Nm inet_aton ,
41.Nm inet_addr , 37.Nm inet_addr ,
38.Nm inet_aton ,
39.Nm inet_lnaof ,
40.Nm inet_makeaddr ,
41.Nm inet_netof ,
42.Nm inet_network , 42.Nm inet_network ,
43.Nm inet_ntoa , 43.Nm inet_ntoa ,
44.Nm inet_makeaddr , 44.Nm inet_ntop ,
45.Nm inet_lnaof , 45.Nm inet_pton
46.Nm inet_netof
47.Nd Internet address manipulation routines 46.Nd Internet address manipulation routines
48.Sh SYNOPSIS 47.Sh SYNOPSIS
48.Fd #include <sys/types.h>
49.Fd #include <sys/socket.h> 49.Fd #include <sys/socket.h>
50.Fd #include <netinet/in.h> 50.Fd #include <netinet/in.h>
51.Fd #include <arpa/inet.h> 51.Fd #include <arpa/inet.h>
52.Ft int 52.Ft in_addr_t
53.Fn inet_aton "const char *cp" "struct in_addr *pin"
54.Ft unsigned long
55.Fn inet_addr "const char *cp" 53.Fn inet_addr "const char *cp"
56.Ft unsigned long 54.Ft int
55.Fn inet_aton "const char *cp" "struct in_addr *addr"
56.Ft in_addr_t
57.Fn inet_lnaof "struct in_addr in"
58.Ft struct in_addr
59.Fn inet_makeaddr "in_addr_t net" "in_addr_t lna"
60.Ft in_addr_t
61.Fn inet_netof "struct in_addr in"
62.Ft in_addr_t
57.Fn inet_network "const char *cp" 63.Fn inet_network "const char *cp"
58.Ft char * 64.Ft char *
59.Fn inet_ntoa "struct in_addr in" 65.Fn inet_ntoa "struct in_addr in"
60.Ft struct in_addr 66.Ft const char *
61.Fn inet_makeaddr "int net" "int lna" 67.Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size"
62.Ft unsigned long 68.Ft int
63.Fn inet_lnaof "struct in_addr in" 69.Fn inet_pton "int af" "const char *src" "void *dst"
64.Ft unsigned long
65.Fn inet_netof "struct in_addr in"
66.Sh DESCRIPTION 70.Sh DESCRIPTION
67The routines 71The routines
68.Fn inet_aton , 72.Fn inet_aton ,
69.Fn inet_addr 73.Fn inet_addr ,
70and 74and
71.Fn inet_network 75.Fn inet_network
72interpret character strings representing 76interpret character strings representing
73numbers expressed in the Internet standard 77numbers expressed in the Internet standard
74.Ql \&. 78.Dq dot
75notation. 79notation.
76The 80The
81.Fn inet_pton
82function converts a presentation format address (that is, printable form
83as held in a character string) to network format (usually a
84.Li struct in_addr
85or some other internal binary representation, in network byte order).
86It returns 1 if the address was valid for the specified address family;
870 if the address wasn't parseable in the specified address family; or \-1
88if some system error occurred (in which case
89.Va errno
90will have been set).
91This function is presently valid for
92.Dv AF_INET
93and
94.Dv AF_INET6 .
95The
77.Fn inet_aton 96.Fn inet_aton
78routine interprets the specified character string as an Internet address, 97routine interprets the specified character string as an Internet address,
79placing the address into the structure provided. 98placing the address into the structure provided.
80It returns 1 if the string was successfully interpreted, 99It returns 1 if the string was successfully interpreted,
81or 0 if the string is invalid. 100or 0 if the string was invalid.
82The 101The
83.Fn inet_addr 102.Fn inet_addr
84and 103and
@@ -86,17 +105,29 @@ and
86functions return numbers suitable for use 105functions return numbers suitable for use
87as Internet addresses and Internet network 106as Internet addresses and Internet network
88numbers, respectively. 107numbers, respectively.
108.Pp
109The function
110.Fn inet_ntop
111converts an address from network format (usually a
112.Li struct in_addr
113or some other binary form, in network byte order) to presentation format
114(suitable for external display purposes).
115It returns
116.Dv NULL
117if a system
118error occurs (in which case,
119.Va errno
120will have been set), or it returns a pointer to the destination string.
89The routine 121The routine
90.Fn inet_ntoa 122.Fn inet_ntoa
91takes an Internet address and returns an 123takes an Internet address and returns an
92.Tn ASCII 124ASCII string representing the address in dot notation.
93string representing the address in 125The routine
94.Ql \&.
95notation. The routine
96.Fn inet_makeaddr 126.Fn inet_makeaddr
97takes an Internet network number and a local 127takes an Internet network number and a local
98network address and constructs an Internet address 128network address and constructs an Internet address
99from it. The routines 129from it.
130The routines
100.Fn inet_netof 131.Fn inet_netof
101and 132and
102.Fn inet_lnaof 133.Fn inet_lnaof
@@ -108,11 +139,8 @@ All Internet addresses are returned in network
108order (bytes ordered from left to right). 139order (bytes ordered from left to right).
109All network numbers and local address parts are 140All network numbers and local address parts are
110returned as machine format integer values. 141returned as machine format integer values.
111.Sh INTERNET ADDRESSES 142.Sh INTERNET ADDRESSES (IP VERSION 4)
112Values specified using the 143Values specified using dot notation take one of the following forms:
113.Ql \&.
114notation take one
115of the following forms:
116.Bd -literal -offset indent 144.Bd -literal -offset indent
117a.b.c.d 145a.b.c.d
118a.b.c 146a.b.c
@@ -122,28 +150,25 @@ a
122.Pp 150.Pp
123When four parts are specified, each is interpreted 151When four parts are specified, each is interpreted
124as a byte of data and assigned, from left to right, 152as a byte of data and assigned, from left to right,
125to the four bytes of an Internet address. Note 153to the four bytes of an Internet address.
126that when an Internet address is viewed as a 32-bit 154Note that when an Internet address is viewed as a 32-bit
127integer quantity on the 155integer quantity on a system that uses little-endian
128.Tn VAX 156byte order
129the bytes referred to 157(such as the Intel 386, 486 and Pentium processors)
130above appear as 158the bytes referred to above appear as
131.Dq Li d.c.b.a . 159.Dq Li d.c.b.a .
132That is, 160That is, little-endian bytes are ordered from right to left.
133.Tn VAX
134bytes are
135ordered from right to left.
136.Pp 161.Pp
137When a three part address is specified, the last 162When a three part address is specified, the last
138part is interpreted as a 16-bit quantity and placed 163part is interpreted as a 16-bit quantity and placed
139in the right-most two bytes of the network address. 164in the rightmost two bytes of the network address.
140This makes the three part address format convenient 165This makes the three part address format convenient
141for specifying Class B network addresses as 166for specifying Class B network addresses as
142.Dq Li 128.net.host . 167.Dq Li 128.net.host .
143.Pp 168.Pp
144When a two part address is supplied, the last part 169When a two part address is supplied, the last part
145is interpreted as a 24-bit quantity and placed in 170is interpreted as a 24-bit quantity and placed in
146the right most three bytes of the network address. 171the rightmost three bytes of the network address.
147This makes the two part address format convenient 172This makes the two part address format convenient
148for specifying Class A network addresses as 173for specifying Class A network addresses as
149.Dq Li net.host . 174.Dq Li net.host .
@@ -154,13 +179,88 @@ rearrangement.
154.Pp 179.Pp
155All numbers supplied as 180All numbers supplied as
156.Dq parts 181.Dq parts
157in a 182in a dot notation
158.Ql \&.
159notation
160may be decimal, octal, or hexadecimal, as specified 183may be decimal, octal, or hexadecimal, as specified
161in the C language (i.e., a leading 0x or 0X implies 184in the C language (i.e., a leading 0x or 0X implies
162hexadecimal; otherwise, a leading 0 implies octal; 185hexadecimal; a leading 0 implies octal;
163otherwise, the number is interpreted as decimal). 186otherwise, the number is interpreted as decimal).
187.Sh INTERNET ADDRESSES (IP VERSION 6)
188In order to support scoped IPv6 addresses,
189.Xr getaddrinfo 3
190and
191.Xr getnameinfo 3
192are recommended rather than the functions presented here.
193.Pp
194The presentation format of an IPv6 address is given in RFC 2373:
195.Pp
196There are three conventional forms for representing IPv6 addresses as
197text strings:
198.Bl -enum
199.It
200The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
201hexadecimal values of the eight 16-bit pieces of the address.
202Examples:
203.Bd -literal -offset indent
204FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2051080:0:0:0:8:800:200C:417A
206.Ed
207.Pp
208Note that it is not necessary to write the leading zeros in an
209individual field, but there must be at least one numeral in
210every field (except for the case described in 2.).
211.It
212Due to the method of allocating certain styles of IPv6
213addresses, it will be common for addresses to contain long
214strings of zero bits.
215In order to make writing addresses
216containing zero bits easier, a special syntax is available to
217compress the zeros.
218The use of
219.Dq \&:\&:
220indicates multiple groups
221of 16 bits of zeros.
222The
223.Dq \&:\&:
224can only appear once in an
225address.
226The
227.Dq \&:\&:
228can also be used to compress the leading and/or trailing zeros in an address.
229.Pp
230For example the following addresses:
231.Bd -literal -offset indent
2321080:0:0:0:8:800:200C:417A a unicast address
233FF01:0:0:0:0:0:0:43 a multicast address
2340:0:0:0:0:0:0:1 the loopback address
2350:0:0:0:0:0:0:0 the unspecified addresses
236.Ed
237.Pp
238may be represented as:
239.Bd -literal -offset indent
2401080::8:800:200C:417A a unicast address
241FF01::43 a multicast address
242::1 the loopback address
243:: the unspecified addresses
244.Ed
245.It
246An alternative form that is sometimes more convenient when
247dealing with a mixed environment of IPv4 and IPv6 nodes is
248x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
249of the six high-order 16-bit pieces of the address, and the 'd's
250are the decimal values of the four low-order 8-bit pieces of the
251address (standard IPv4 representation).
252Examples:
253.Bd -literal -offset indent
2540:0:0:0:0:0:13.1.68.3
2550:0:0:0:0:FFFF:129.144.52.38
256.Ed
257.Pp
258or in compressed form:
259.Bd -literal -offset indent
260::13.1.68.3
261::FFFF:129.144.52.38
262.Ed
263.El
164.Sh DIAGNOSTICS 264.Sh DIAGNOSTICS
165The constant 265The constant
166.Dv INADDR_NONE 266.Dv INADDR_NONE
@@ -170,28 +270,76 @@ and
170.Fn inet_network 270.Fn inet_network
171for malformed requests. 271for malformed requests.
172.Sh SEE ALSO 272.Sh SEE ALSO
273.Xr byteorder 3 ,
173.Xr gethostbyname 3 , 274.Xr gethostbyname 3 ,
174.Xr getnetent 3 , 275.Xr getnetent 3 ,
276.Xr inet_net 3 ,
175.Xr hosts 5 , 277.Xr hosts 5 ,
176.Xr networks 5 , 278.Xr networks 5
279.Rs
280.%R RFC 2373
281.%D July 1998
282.%T "IP Version 6 Addressing Architecture"
283.Re
284.Rs
285.%R RFC 3493
286.%D February 2003
287.%T "Basic Socket Interface Extensions for IPv6"
288.Re
289.Sh STANDARDS
290The
291.Nm inet_ntop
292and
293.Nm inet_pton
294functions conform to the IETF IPv6 BSD API and address formatting
295specifications.
296Note that
297.Nm inet_pton
298does not accept 1-, 2-, or 3-part dotted addresses; all four parts
299must be specified.
300This is a narrower input set than that accepted by
301.Nm inet_aton .
177.Sh HISTORY 302.Sh HISTORY
178These 303The
179functions appeared in 304.Nm inet_addr ,
305.Nm inet_network ,
306.Nm inet_makeaddr ,
307.Nm inet_lnaof ,
308and
309.Nm inet_netof
310functions appeared in
180.Bx 4.2 . 311.Bx 4.2 .
312The
313.Nm inet_aton
314and
315.Nm inet_ntoa
316functions appeared in
317.Bx 4.3 .
318The
319.Nm inet_pton
320and
321.Nm inet_ntop
322functions appeared in BIND 4.9.4.
181.Sh BUGS 323.Sh BUGS
182The value 324The value
183.Dv INADDR_NONE 325.Dv INADDR_NONE
184(0xffffffff) is a valid broadcast address, but 326(0xffffffff) is a valid broadcast address, but
185.Fn inet_addr 327.Fn inet_addr
186cannot return that value without indicating failure. 328cannot return that value without indicating failure.
329Also,
330.Fn inet_addr
331should have been designed to return a
332.Li struct in_addr .
187The newer 333The newer
188.Fn inet_aton 334.Fn inet_aton
189function does not share this problem. 335function does not share these problems, and almost all existing code
336should be modified to use
337.Fn inet_aton
338instead.
339.Pp
190The problem of host byte ordering versus network byte ordering is 340The problem of host byte ordering versus network byte ordering is
191confusing. 341confusing.
342.Pp
192The string returned by 343The string returned by
193.Fn inet_ntoa 344.Fn inet_ntoa
194resides in a static memory area. 345resides in a static memory area.
195.Pp
196Inet_addr should return a
197.Fa struct in_addr .
diff --git a/src/lib/libc/net/inet6_opt_init.3 b/src/lib/libc/net/inet6_opt_init.3
new file mode 100644
index 0000000000..21880a6382
--- /dev/null
+++ b/src/lib/libc/net/inet6_opt_init.3
@@ -0,0 +1,338 @@
1.\" $OpenBSD: inet6_opt_init.3,v 1.3 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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
63Building and parsing the Hop-by-Hop and Destination options is
64complicated.
65The advanced sockets API defines a set of functions to
66help applications create and manipulate Hop-by-Hop and Destination
67options.
68.\"This man page describes the functions specified in
69.\"IETF Draft RFC 3542 while the
70.\".Xr inet6_options_space 3
71.\"man page documents the functions defined in RFC 2292.
72.\"It is expected
73.\"that this set of functions will supersede those in RFC 2292 but for
74.\"the time being both APIs are retained.
75These functions use the
76formatting rules specified in Appendix B in RFC 2460, i.e. that the
77largest field is placed last in the option.
78The function prototypes
79for these functions are all contained in the header file
80.Aq Pa netinet/in.h .
81.\"
82.Ss inet6_opt_init
83The
84.Fn inet6_opt_init
85function
86returns the number of bytes needed for an empty
87extension header, one without any options.
88If the
89.Va extbuf
90argument points to a valid section of memory
91then the
92.Fn inet6_opt_init
93function also initializes the extension header's length field.
94When attempting to initialize an extension buffer passed in the
95.Va extbuf
96argument,
97.Fa extlen
98must be a positive multiple of 8 or else the function fails and
99returns \-1 to the caller.
100.\"
101.Ss inet6_opt_append
102The
103.Fn inet6_opt_append
104function can perform different jobs.
105When a valid
106.Fa extbuf
107argument is supplied it appends an option to the extension buffer and
108returns the updated total length as well as a pointer to the newly
109created option in
110.Fa databufp .
111If the value
112of
113.Fa extbuf
114is
115.Dv NULL
116then the
117.Fn inet6_opt_append
118function only reports what the total length would
119be if the option were actually appended.
120The
121.Fa len
122and
123.Fa align
124arguments specify the length of the option and the required data
125alignment which must be used when appending the option.
126The
127.Fa offset
128argument should be the length returned by the
129.Fn inet6_opt_init
130function or a previous call to
131.Fn inet6_opt_append .
132.Pp
133The
134.Fa type
135argument is the 8-bit option type.
136.Pp
137After
138.Fn inet6_opt_append
139has been called, the application can use the buffer pointed to by
140.Fa databufp
141directly, or use
142.Fn inet6_opt_set_val
143to specify the data to be contained in the option.
144.Pp
145Option types of
146.Li 0
147and
148.Li 1
149are reserved for the
150.Li Pad1
151and
152.Li PadN
153options.
154All other values from 2 through 255 may be used by applications.
155.Pp
156The length of the option data is contained in an 8-bit value and so
157may contain any value from 0 through 255.
158.Pp
159The
160.Fa align
161parameter must have a value of 1, 2, 4, or 8 and cannot exceed the
162value of
163.Fa len .
164The alignment values represent no alignment, 16-bit, 32-bit and 64-bit
165alignments respectively.
166.\"
167.Ss inet6_opt_finish
168The
169.Fn inet6_opt_finish
170calculates the final padding necessary to make the extension header a
171multiple of 8 bytes, as required by the IPv6 extension header
172specification, and returns the extension header's updated total
173length.
174The
175.Fa offset
176argument should be the length returned by
177.Fn inet6_opt_init
178or
179.Fn inet6_opt_append .
180When
181.Fa extbuf
182is not
183.Dv NULL
184the function also sets up the appropriate padding bytes by inserting a
185Pad1 or PadN option of the proper length.
186.Pp
187If the extension header is too small to contain the proper padding
188then an error of \-1 is returned to the caller.
189.\"
190.Ss inet6_opt_set_val
191The
192.Fn inet6_opt_set_val
193function inserts data items of various sizes into the data portion of
194the option.
195The
196.Fa databuf
197argument is a pointer to memory that was returned by the
198.Fn inet6_opt_append
199call and the
200.Fa offset
201argument specifies where the option should be placed in the
202data buffer.
203The
204.Fa val
205argument points to an area of memory containing the data to be
206inserted into the extension header, and the
207.Fa vallen
208argument indicates how much data to copy.
209.Pp
210The caller should ensure that each field is aligned on its natural
211boundaries as described in Appendix B of RFC 2460.
212.Pp
213The function returns the offset for the next field which is calculated as
214.Fa offset
215+
216.Fa vallen
217and is used when composing options with multiple fields.
218.\"
219.Ss inet6_opt_next
220The
221.Fn inet6_opt_next
222function parses received extension headers.
223The
224.Fa extbuf
225and
226.Fa extlen
227arguments specify the location and length of the extension header
228being parsed.
229The
230.Fa offset
231argument should either be zero, for the first option, or the length value
232returned by a previous call to
233.Fn inet6_opt_next
234or
235.Fn inet6_opt_find .
236The return value specifies the position where to continue scanning the
237extension buffer.
238The option is returned in the arguments
239.Fa typep , lenp ,
240and
241.Fa databufp .
242.Fa typep , lenp ,
243and
244.Fa databufp
245point to the 8-bit option type, the 8-bit option length and the option
246data respectively.
247This function does not return any PAD1 or PADN options.
248When an error occurs or there are no more options the return
249value is \-1.
250.\"
251.Ss inet6_opt_find
252The
253.Fn inet6_opt_find
254function searches the extension buffer for a particular option type,
255passed in through the
256.Fa type
257argument.
258If the option is found then the
259.Fa lenp
260and
261.Fa databufp
262arguments are updated to point to the option's length and data
263respectively.
264.Fa extbuf
265and
266.Fa extlen
267must point to a valid extension buffer and give its length.
268The
269.Fa offset
270argument can be used to search from a location anywhere in the
271extension header.
272.Ss inet6_opt_get_val
273The
274.Fn inet6_opt_get_val
275function extracts data items of various sizes in the data portion of
276the option.
277The
278.Fa databuf
279is a pointer returned by the
280.Fn inet6_opt_next
281or
282.Fn inet6_opt_find
283functions.
284The
285.Fa val
286argument points to where the data will be extracted.
287The
288.Fa offset
289argument specifies from where in the data portion of the option the
290value should be extracted; the first byte of option data is specified
291by an offset of zero.
292.Pp
293It is expected that each field is aligned on its natural boundaries as
294described in Appendix B of RFC 2460.
295.Pp
296The function returns the offset for the next field
297by calculating
298.Fa offset
299+
300.Fa vallen
301which can be used when extracting option content with multiple fields.
302Robust receivers must verify alignment before calling this function.
303.\"
304.Sh EXAMPLES
305RFC 3542 gives comprehensive examples in Section 23.
306KAME also provides examples in the
307.Pa advapitest
308directory of its kit.
309.\"
310.Sh DIAGNOSTICS
311All the functions return
312\-1
313on an error.
314.\"
315.Sh SEE ALSO
316.Rs
317.%A W. Stevens
318.%A M. Thomas
319.%A E. Nordmark
320.%A T. Jinmei
321.%T "Advanced Sockets API for IPv6"
322.%N RFC 3542
323.%D October 2002
324.Re
325.Rs
326.%A S. Deering
327.%A R. Hinden
328.%T "Internet Protocol, Version 6 (IPv6) Specification"
329.%N RFC 2460
330.%D December 1998
331.Re
332.Sh STANDARDS
333The functions are documented in
334.Dq Advanced Sockets API for IPv6
335.Pq RFC 3542 .
336.Sh HISTORY
337The implementation first appeared in KAME advanced networking kit.
338.\"
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..8aa79a6d0b
--- /dev/null
+++ b/src/lib/libc/net/inet6_option_space.3
@@ -0,0 +1,444 @@
1.\" $OpenBSD: inet6_option_space.3,v 1.21 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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.\"
62Note:
63RFC 2292 has been superseded by RFC 3542.
64The use of functions described in this page is deprecated.
65See
66.Xr inet6_opt_init 3 .
67.Pp
68Manipulating and parsing IPv6's Hop-by-Hop and Destination options is
69complicated by the need to properly align and pad data as well as the
70need to manipulate ancillary information that is not part of the data
71stream.
72RFC 2292 defines a set of functions, which are implemented as
73part of the Kame libraries, to help developers create, change,
74and parse Hop-by-Hop and Destination options.
75All of the prototypes
76for the option functions are defined in the
77.Aq Pa netinet/in.h
78header file.
79.\"
80.Ss inet6_option_space
81In order to determine the amount of space necessary to hold any option
82the
83.Fn inet6_option_space
84function is called.
85It returns the number of bytes required to hold
86an option when it is stored as ancillary data, including the
87.Li cmsghdr
88structure at the beginning, and any necessary padding at the end.
89The
90.Fa nbytes
91argument indicates the size of the structure defining the option,
92and must include any pad bytes at the beginning (the value
93.Li y
94in the alignment term
95.Dq Li "xn + y" ) ,
96the type byte, the length byte, and the option data.
97.Pp
98Note: If multiple options are stored in a single ancillary data
99object, which is the recommended technique, the
100.Fn inet6_option_space
101function overestimates the amount of space required by the size of
102.Li N-1
103.Li cmsghdr
104structures, where
105.Li N
106is the number of options to be stored in the object.
107Usually this has
108no impact because it is assumed that most Hop-by-Hop and Destination
109option headers carry only one option as indicated in appendix B of RFC 2460.
110.\"
111.Ss inet6_option_init
112The
113.Fn inet6_option_init
114function is called to initialize any ancillary data object that will contain
115a Hop-by-Hop or Destination option.
116It returns
117.Li 0
118on success and
119.Li \-1
120when an error occurs.
121.Pp
122The
123.Fa bp
124argument points to a previously allocated area of memory which must be
125large enough to contain all the arguments that the application intends
126to add later via the
127.Fn inet6_option_append
128and
129.Fn inet6_option_alloc
130routines.
131.Pp
132The
133.Fa cmsgp
134argument is a pointer to a pointer to a
135.Li cmsghdr
136structure.
137The
138.Fa *cmsgp
139argument
140points to a
141.Li cmsghdr
142structure which is constructed by this function and stored in the
143area of memory pointed to by
144.Fa bp .
145.Pp
146The
147.Fa type
148is either
149.Dv IPV6_HOPOPTS
150or
151.Dv IPV6_DSTOPTS
152and is stored in the
153.Li cmsg_type
154member of the
155.Li cmsghdr
156structure mentioned above.
157.\"
158.Ss inet6_option_append
159This function appends a Hop-by-Hop option or a Destination option into
160an ancillary data object previously initialized by a call to
161.Fn inet6_option_init .
162The
163.Fn inet6_option_append
164function returns
165.Li 0
166if it succeeds or
167.Li \-1
168when an error occurs.
169.Pp
170The
171.Fa cmsg
172argument is a pointer to the
173.Li cmsghdr
174structure that was initialized by a call to
175.Fn inet6_option_init .
176.Pp
177The
178.Fa typep
179argument is a pointer to the 8-bit option type.
180All options are
181encoded as type-length-value tuples and it is assumed that
182the
183.Fa typep
184field is immediately followed by the 8-bit option data length field,
185which is then followed by the option data.
186.Pp
187The option types of
188.Li 0
189and
190.Li 1
191are reserved for the
192.Li Pad1
193and
194.Li PadN
195options respectively.
196All other values from
197.Li 2
198through
199.Li 255
200are available for applications to use.
201.Pp
202The option data length, since it is stored in 8 bites, must have a
203value between
204.Li 0
205and
206.Li 255 ,
207inclusive.
208.Pp
209The
210.Fa multx
211argument
212is the value
213.Li x
214in the alignment term
215.Dq Li xn + y
216and indicates the byte alignment necessary for the data.
217Alignments may be specified as
218.Li 1 ,
219.Li 2 ,
220.Li 4 ,
221or
222.Li 8
223bytes, which is no alignment, 16-bit, 32-bit and 64-bit alignments
224respectively.
225.Pp
226The
227.Fa plusy
228argument
229is the value
230.Li y
231in the alignment term
232.Dq Li xn + y
233and must have a value between
234.Li 0
235and
236.Li 7 ,
237inclusive, indicating the amount of padding that is necessary for an
238option.
239.\"
240.Ss inet6_option_alloc
241The
242.Fn inet6_option_alloc
243function appends a Hop-by-Hop option or a Destination option into an
244ancillary data object that has previously been initialized by a call to
245.Fn inet6_option_init .
246A successful call to the
247.Fn inet6_option_alloc
248function returns a pointer to the 8-bit option type field,
249which is at the beginning of the allocated region.
250.Fn inet6_option_alloc
251returns
252.Dv NULL
253when an error has occurred.
254.Pp
255The difference between the
256.Fn inet6_option_alloc
257and
258.Fn inet6_option_append
259functions is that the latter copies the contents of a previously built
260option into the ancillary data object while the former returns a
261pointer to the place in the data object where the option's TLV must
262then be built by the application.
263.Pp
264The
265.Fa cmsg
266argument is a pointer to a
267.Li cmsghdr
268structure that was initialized by
269.Fn inet6_option_init .
270.Pp
271The
272.Fa datalen
273argument is the value of the option data length byte for this option.
274This value is required as an argument to allow the function to
275determine if padding must be appended at the end of the option.
276(The
277.Fn inet6_option_append
278function does not need a data length argument
279since the option data length must already be stored by the caller.)
280.Pp
281The
282.Fa multx
283and
284.Fa plusy
285arguments
286are identical to the arguments of the same name described in the
287.Fn inet6_option_init
288function above.
289.\"
290.Ss inet6_option_next
291The
292.Fn inet6_option_next
293function is used to process Hop-by-Hop and Destination options that
294are present in an ancillary data object.
295When an option remains to
296be processed, the return value of the
297.Fn inet6_option_next
298function is
299.Li 0
300and the
301.Fa *tptrp
302argument points to the 8-bit option type field, which is followed by
303the 8-bit option data length, and then the option data.
304When no more
305options remain to be processed, the return value is
306.Li \-1
307and
308.Fa *tptrp
309is
310.Dv NULL .
311When an error occurs, the return value is
312.Li \-1 ,
313but the
314.Fa *tptrp
315argument is not
316.Dv NULL .
317This set of return values allows a program to easily loop through all
318the options in an ancillary data object, checking for the error and
319end of stream conditions along the way.
320.Pp
321When a valid option is returned, the
322.Fa cmsg
323argument points to a
324.Li cmsghdr
325where the
326.Li cmsg_level
327element equals
328.Dv IPPROTO_IPV6
329and the
330.Li cmsg_type
331element is either
332.Dv IPV6_HOPOPTS
333or
334.Dv IPV6_DSTOPTS .
335.Pp
336The
337.Fa tptrp
338argument is a pointer to a pointer to an 8-bit byte and
339.Fa *tptrp
340is used by the function to remember its place in the ancillary data
341object each time the function is called.
342When the
343.Fn inet6_option_next
344function is called for the first time on a given ancillary data object,
345.Fa *tptrp
346must be set to
347.Dv NULL .
348.Pp
349Each time the function returns success,
350the
351.Fa *tptrp
352argument points to the 8-bit option type field for the next option to
353be processed.
354.\"
355.Ss inet6_option_find
356The
357.Fn inet6_option_find
358function allows an application to search for a particular option type
359in an ancillary data object.
360The
361.Fa cmsg
362argument is a pointer to a
363.Li cmsghdr
364structure in which the
365.Li cmsg_level
366element equals
367.Dv IPPROTO_IPV6
368and the
369.Li cmsg_type
370element is either
371.Dv IPV6_HOPOPTS
372or
373.Dv IPV6_DSTOPTS .
374.Pp
375The
376.Fa tptrp
377argument is handled exactly as in the
378.Fn inet6_option_next
379function described above.
380.Pp
381The
382.Fn inet6_option_find
383function starts searching for an option of the specified type
384beginning after the value of
385.Fa *tptrp .
386.\"
387.Sh EXAMPLES
388RFC 2292 gives comprehensive examples in chapter 6.
389.\"
390.Sh DIAGNOSTICS
391The
392.Fn inet6_option_init
393and
394.Fn inet6_option_append
395functions return
396.Li 0
397on success or
398.Li \-1
399on an error.
400.Pp
401The
402.Fn inet6_option_alloc
403function returns
404.Dv NULL
405on an error.
406.Pp
407When
408.Fn inet6_option_next
409or
410.Fn inet6_option_find
411detect an error they return
412.Li \-1 ,
413setting
414.Fa *tptrp
415to a non
416.Dv NULL
417value.
418.\"
419.Sh SEE ALSO
420.Xr inet6 4 ,
421.Xr ip6 4
422.Rs
423.%A W. Stevens
424.%A M. Thomas
425.%T "Advanced Sockets API for IPv6"
426.%N RFC 2292
427.%D February 1998
428.Re
429.Rs
430.%A S. Deering
431.%A R. Hinden
432.%T "Internet Protocol, Version 6 (IPv6) Specification"
433.%N RFC 2460
434.%D December 1998
435.Re
436.\"
437.Sh STANDARDS
438The functions are documented in
439.Dq Advanced Sockets API for IPv6
440(RFC 2292).
441.\"
442.Sh HISTORY
443This implementation first appeared in the KAME advanced networking kit.
444.\"
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..326521def7
--- /dev/null
+++ b/src/lib/libc/net/inet6_rth_space.3
@@ -0,0 +1,219 @@
1.\" $OpenBSD: inet6_rth_space.3,v 1.3 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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
60The IPv6 Advanced API, RFC 3542, defines the functions that an
61application calls to build and examine IPv6 Routing headers.
62Routing headers are used to perform source routing in IPv6 networks.
63The RFC uses the word
64.Dq segments
65to describe addresses and that is the term used here as well.
66All of the functions are defined in the header file
67.Aq Pa netinet/in.h .
68The functions described in this manual page all operate
69on routing header structures which are defined in
70.Aq Pa netinet/ip6.h
71but which should not need to be modified outside the use of this API.
72The size and shape of the route header structures may change, so using
73the APIs is a more portable, long term, solution.
74.Pp
75The functions in the API are split into two groups, those that build a
76routing header and those that parse a received routing header.
77The builder functions are described first, followed by the parser functions.
78.Ss inet6_rth_space
79The
80.Fn inet6_rth_space
81function returns the number of bytes required to hold a Routing Header
82of the type, specified in the
83.Fa type
84argument and containing the number of addresses specified in the
85.Fa segments
86argument.
87When the type is
88.Dv IPV6_RTHDR_TYPE_0
89the number of segments must be from 0 through 127.
90The return value from this function is the number of bytes required to
91store the routing header.
92If the value 0 is returned then either the
93route header type was not recognized or another error occurred.
94.Ss inet6_rth_init
95The
96.Fn inet6_rth_init
97function initializes the pre-allocated buffer pointed to by
98.Fa bp
99to contain a routing header of the specified type.
100The
101.Fa bp_len
102argument is used to verify that the buffer is large enough.
103The caller must allocate the buffer pointed to by bp.
104The necessary buffer size should be determined by calling
105.Fn inet6_rth_space
106described in the previous sections.
107.Pp
108The
109.Fn inet6_rth_init
110function returns a pointer to
111.Fa bp
112on success and
113.Dv NULL
114when there is an error.
115.Ss inet6_rth_add
116The
117.Fn inet6_rth_add
118function adds the IPv6 address pointed to by
119.Fa addr
120to the end of the routing header being constructed.
121.Pp
122A successful addition results in the function returning 0, otherwise
123\-1 is returned.
124.Ss inet6_rth_reverse
125The
126.Fn inet6_rth_reverse
127function takes a routing header, pointed to by the
128argument
129.Fa in ,
130and writes a new routing header into the argument pointed to by
131.Fa out .
132The routing header at that sends datagrams along the reverse of that
133route.
134Both arguments are allowed to point to the same buffer meaning
135that the reversal can occur in place.
136.Pp
137The return value of the function is 0 on success, or \-1 when
138there is an error.
139.\"
140.Pp
141The next set of functions operate on a routing header that the
142application wants to parse.
143In the usual case such a routing header
144is received from the network, although these functions can also be
145used with routing headers that the application itself created.
146.Ss inet6_rth_segments
147The
148.Fn inet6_rth_segments
149function returns the number of segments contained in the
150routing header pointed to by
151.Fa bp .
152The return value is the number of segments contained in the routing
153header, or \-1 if an error occurred.
154It is not an error for 0 to be
155returned as a routing header may contain 0 segments.
156.\"
157.Ss inet6_rth_getaddr
158The
159.Fn inet6_rth_getaddr
160function is used to retrieve a single address from a routing header.
161The
162.Fa index
163is the location in the routing header from which the application wants
164to retrieve an address.
165The
166.Fa index
167parameter must have a value between 0 and one less than the number of
168segments present in the routing header.
169The
170.Fn inet6_rth_segments
171function, described in the last section, should be used to determine
172the total number of segments in the routing header.
173The
174.Fn inet6_rth_getaddr
175function returns a pointer to an IPv6 address on success or
176.Dv NULL
177when an error has occurred.
178.\"
179.Sh EXAMPLES
180RFC 3542 gives extensive examples in Section 21, Appendix B.
181KAME also provides examples in the advapitest directory of its kit.
182.\"
183.Sh DIAGNOSTICS
184The
185.Fn inet6_rth_space
186and
187.Fn inet6_rth_getaddr
188functions return 0 on errors.
189.Pp
190The
191.Fn inet6_rthdr_init
192function returns
193.Dv NULL
194on error.
195The
196.Fn inet6_rth_add
197and
198.Fn inet6_rth_reverse
199functions return 0 on success, or \-1 upon an error.
200.\"
201.Sh SEE ALSO
202.Rs
203.%A W. Stevens
204.%A M. Thomas
205.%A E. Nordmark
206.%A T. Jinmei
207.%T "Advanced Sockets API for IPv6"
208.%N RFC 3542
209.%D May 2003
210.Re
211.Rs
212.%A S. Deering
213.%A R. Hinden
214.%T "Internet Protocol, Version 6 (IPv6) Specification"
215.%N RFC 2460
216.%D December 1998
217.Re
218.Sh HISTORY
219The 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..3287bfe009
--- /dev/null
+++ b/src/lib/libc/net/inet6_rthdr_space.3
@@ -0,0 +1,314 @@
1.\" $OpenBSD: inet6_rthdr_space.3,v 1.20 2007/05/31 19:19:30 jmc 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: May 31 2007 $
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.\"The RFC 2292 IPv6 Advanced API has been deprecated in favor of the
68.\"newer, RFC 3542 APIs.
69.\"On platforms that support it, currently only
70.\"FreeBSD, please use the newer API to manipulate routing header
71.\"options.
72.\".Pp
73Note:
74RFC 2292 has been superseded by RFC 3542.
75The use of functions described in this page is deprecated.
76See
77.Xr inet6_rth_space 3 .
78.Pp
79The RFC 2292 IPv6 Advanced API defined eight functions for
80applications to use for building and parsing routing headers.
81The
82eight functions are split into two groups, the first of which builds
83the header and the second of which can parse it.
84The function prototypes for these functions are all in the
85.Aq Pa netinet/in.h
86header.
87Although direct manipulation of a routing header is possible,
88this set of APIs make it unnecessary and such direct manipulation
89should be avoided so that changes to the underlying structures do not
90break applications.
91.Pp
92Please note that RFC 2292 uses the term
93.Dq segments
94instead of the term
95.Dq addresses
96but they are considered equivalent for this manual page.
97.\"
98.Ss inet6_rthdr_space
99The
100.Fn inet6_rthdr_space
101function returns the number of bytes required to hold a routing header
102of the specified
103.Fa type
104and containing the specified number of
105.Fa segments .
106Only one
107.Fa type
108is supported,
109.Dv IPV6_RTHDR_TYPE_0 ,
110and it can hold from 1 to 23 segments.
111The return value includes the
112size of the
113.Vt cmsghdr
114structure that precedes the routing header and
115any required padding.
116.Pp
117A return value of 0 indicates an error.
118Either the type was specified
119incorrectly, or the number of segments was less than one or greater
120than 23.
121.Pp
122Note: The
123.Fn inet6_rthdr_space
124function only returns the size required by the routing header and does
125not allocate memory for the caller.
126.\"
127.Ss inet6_rthdr_init
128The
129.Fn inet6_rthdr_init
130function initializes a buffer, pointed to by
131.Fa bp
132with an appropriate
133.Li cmsghdr
134structure followed by a routing header of the specified
135.Fa type .
136.Pp
137The caller must use the
138.Fn inet6_rthdr_space
139function to determine the size of the buffer, and then allocate that
140buffer before calling
141.Fn inet6_rthdr_init .
142.Pp
143The return value is a pointer to a
144.Li cmsghdr
145structure, which is used as the first argument to the
146.Fn inet6_rthdr_add
147and
148.Fn inet6_rthdr_lasthop
149functions in order to construct the routing header.
150When an error occurs the return value is
151.Dv NULL .
152.\"
153.Ss inet6_rthdr_add
154The
155.Fn inet6_rthdr_add
156function adds the IPv6 address pointed to by
157.Fa addr
158to the end of the
159routing header being constructed and sets the type of this address to the
160value of
161.Fa flags .
162The
163.Fa flags
164must be either
165.Dv IPV6_RTHDR_LOOSE
166or
167.Dv IPV6_RTHDR_STRICT
168indicating whether loose or strict source routing is required.
169.Pp
170When the function succeeds it returns 0, otherwise \-1 is returned.
171.\"
172.Ss inet6_rthdr_lasthop
173The
174.Fn inet6_rthdr_lasthop
175function specifies the strict or loose flag for the final hop of a
176routing header.
177The
178.Fa flags
179argument must be either
180.Dv IPV6_RTHDR_LOOSE
181or
182.Dv IPV6_RTHDR_STRICT .
183.Pp
184The return value of the function is 0 upon success, and \-1 when an
185error has occurred.
186.Pp
187Please note that a routing header specifying
188.Li N
189intermediate nodes requires
190.Li N+1
191strict or loose flags meaning that
192.Fn inet6_rthdr_add
193must be called
194.Li N
195times and then
196.Fn inet6_rthdr_lasthop
197must be called once.
198.\"
199.Ss inet6_rthdr_reverse
200This function was never implemented.
201.Pp
202The following three functions provide an API for parsing a received
203routing header:
204.\"
205.Ss inet6_rthdr_segments
206The
207.Fn inet6_rthdr_segments
208function returns the number of segments contained in the routing
209header pointed to by the
210.Fa cmsg
211argument.
212On success the return value is from 1 to 23.
213When an error occurs, \-1 is returned.
214.\"
215.Ss inet6_rthdr_getaddr
216The
217.Fn inet6_rthdr_getaddr
218function returns a pointer to the IPv6 address specified by the
219.Fa index
220argument from the routing header pointed to by
221.Fa cmsg .
222The index must be between 1 and the number returned by
223.Fn inet6_rthdr_segments ,
224described above.
225An application must call
226.Fn inet6_rthdr_segments
227to obtain the number of segments in the routing header.
228.Pp
229If an error occurs,
230.Dv NULL
231is returned.
232.\"
233.Ss inet6_rthdr_getflags
234The
235.Fn inet6_rthdr_getflags
236function returns the flags value of the segment specified by
237.Fa index
238of the routing header pointed to by
239.Fa cmsg .
240The
241.Fa index
242argument must be between 0 and the value returned by
243.Fn inet6_rthdr_segments .
244The return value will be either
245.Dv IPV6_RTHDR_LOOSE
246or
247.Dv IPV6_RTHDR_STRICT
248indicating whether loose or strict source routing was requested for
249that segment.
250.Pp
251When an error occurs, \-1 is returned.
252.Pp
253Note: Flags begin at index 0 while segments begin at index 1, to
254maintain consistency with the terminology and figures in RFC 2460.
255.\"
256.Sh EXAMPLES
257RFC 2292 gives comprehensive examples in chapter 8.
258.\"
259.Sh DIAGNOSTICS
260The
261.Fn inet6_rthdr_space
262function returns 0 when an error occurs.
263.Pp
264The
265.Fn inet6_rthdr_add
266and
267.Fn inet6_rthdr_lasthop
268functions return 0 on success, and \-1 on error.
269.Pp
270The
271.Fn inet6_rthdr_init
272and
273.Fn inet6_rthdr_getaddr
274functions
275return
276.Dv NULL
277on error.
278.Pp
279The
280.Fn inet6_rthdr_segments
281and
282.Fn inet6_rthdr_getflags
283functions return \-1 on error.
284.\"
285.Sh SEE ALSO
286.Xr inet6 4 ,
287.Xr ip6 4
288.Rs
289.%A W. Stevens
290.%A M. Thomas
291.%T "Advanced Sockets API for IPv6"
292.%N RFC 2292
293.%D February 1998
294.Re
295.Rs
296.%A S. Deering
297.%A R. Hinden
298.%T "Internet Protocol, Version 6 (IPv6) Specification"
299.%N RFC 2460
300.%D December 1998
301.Re
302.\"
303.Sh HISTORY
304This implementation first appeared in the KAME advanced networking kit.
305.\"
306.Sh BUGS
307The
308.Fn inet6_rthdr_reverse
309function was never implemented.
310.\".Pp
311.\"This API is deprecated in favor of
312.\".Xr inet6_rth_space 3
313.\".Sh SEE ALSO
314.\".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..c962a03382 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.9 2005/08/06 20:30:03 espie 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
38static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
39#else
40static 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 */
53u_long 64in_addr_t
54inet_addr(cp) 65inet_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,60 @@ 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 */
71int 81int
72inet_aton(cp, addr) 82inet_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(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(c) && isdigit(c)) {
97 val = (val * base) + (c - '0'); 109 val = (val * base) + (c - '0');
98 cp++; 110 c = *++cp;
99 continue; 111 } else if (base == 16 && isascii(c) && isxdigit(c)) {
100 } 112 val = (val << 4) |
101 if (base == 16 && isascii(c) && isxdigit(c)) {
102 val = (val << 4) +
103 (c + 10 - (islower(c) ? 'a' : 'A')); 113 (c + 10 - (islower(c) ? 'a' : 'A'));
104 cp++; 114 c = *++cp;
105 continue; 115 } else
106 } 116 break;
107 break;
108 } 117 }
109 if (*cp == '.') { 118 if (c == '.') {
110 /* 119 /*
111 * Internet format: 120 * Internet format:
112 * a.b.c.d 121 * a.b.c.d
113 * a.b.c (with c treated as 16-bits) 122 * a.b.c (with c treated as 16 bits)
114 * a.b (with b treated as 24 bits) 123 * a.b (with b treated as 24 bits)
115 */ 124 */
116 if (pp >= parts + 3 || val > 0xff) 125 if (pp >= parts + 3)
117 return (0); 126 return (0);
118 *pp++ = val, cp++; 127 *pp++ = val;
128 c = *++cp;
119 } else 129 } else
120 break; 130 break;
121 } 131 }
122 /* 132 /*
123 * Check for trailing characters. 133 * Check for trailing characters.
124 */ 134 */
125 if (*cp && (!isascii(*cp) || !isspace(*cp))) 135 if (c != '\0' && (!isascii(c) || !isspace(c)))
126 return (0); 136 return (0);
127 /* 137 /*
128 * Concoct the address according to 138 * Concoct the address according to
@@ -131,23 +141,26 @@ inet_aton(cp, addr)
131 n = pp - parts + 1; 141 n = pp - parts + 1;
132 switch (n) { 142 switch (n) {
133 143
144 case 0:
145 return (0); /* initial nondigit */
146
134 case 1: /* a -- 32 bits */ 147 case 1: /* a -- 32 bits */
135 break; 148 break;
136 149
137 case 2: /* a.b -- 8.24 bits */ 150 case 2: /* a.b -- 8.24 bits */
138 if (val > 0xffffff) 151 if ((val > 0xffffff) || (parts[0] > 0xff))
139 return (0); 152 return (0);
140 val |= parts[0] << 24; 153 val |= parts[0] << 24;
141 break; 154 break;
142 155
143 case 3: /* a.b.c -- 8.8.16 bits */ 156 case 3: /* a.b.c -- 8.8.16 bits */
144 if (val > 0xffff) 157 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
145 return (0); 158 return (0);
146 val |= (parts[0] << 24) | (parts[1] << 16); 159 val |= (parts[0] << 24) | (parts[1] << 16);
147 break; 160 break;
148 161
149 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 162 case 4: /* a.b.c.d -- 8.8.8.8 bits */
150 if (val > 0xff) 163 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
151 return (0); 164 return (0);
152 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 165 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
153 break; 166 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
38static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_lnaof.c,v 1.4 1995/02/25 06:20:42 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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 */
53u_long 40in_addr_t
54inet_lnaof(in) 41inet_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
38static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_makeaddr.c,v 1.4 1995/02/25 06:20:42 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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 */
52struct in_addr 39struct in_addr
53inet_makeaddr(net, host) 40inet_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..648d82c780
--- /dev/null
+++ b/src/lib/libc/net/inet_net.3
@@ -0,0 +1,176 @@
1.\" $OpenBSD: inet_net.3,v 1.14 2008/06/26 05:42:05 ray 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 26 2008 $
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.Fd #include <sys/types.h>
40.Fd #include <sys/socket.h>
41.Fd #include <netinet/in.h>
42.Fd #include <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
48The
49.Fn inet_net_ntop
50function converts an Internet network number from network format (usually a
51.Li struct in_addr
52or some other binary form, in network byte order) to CIDR presentation format
53(suitable for external display purposes).
54.Fa bits
55is the number of bits in
56.Fa src
57that are the network number.
58It returns
59.Dv NULL
60if a system error occurs (in which case,
61.Va errno
62will have been set), or it returns a pointer to the destination string.
63.Pp
64The
65.Fn inet_net_pton
66function converts a presentation format Internet network number (that is,
67printable form as held in a character string) to network format (usually a
68.Li struct in_addr
69or some other internal binary representation, in network byte order).
70It returns the number of bits (either computed based on the class, or
71specified with /CIDR), or \-1 if a failure occurred
72(in which case
73.Va errno
74will have been set.
75It will be set to
76.Er ENOENT
77if the Internet network number was not valid).
78.Pp
79Caution:
80The
81.Fa dst
82field should be zeroed before calling
83.Fn inet_net_pton
84as the function will only fill the number of bytes necessary to
85encode the network number in network byte order.
86.Pp
87The only value for
88.Fa af
89currently supported is
90.Dv AF_INET .
91.Fa size
92is the size of the result buffer
93.Fa dst .
94.Sh NETWORK NUMBERS (IP VERSION 4)
95The external representation of Internet network numbers may be specified in
96one of the following forms:
97.Bd -literal -offset indent
98a
99a.b
100a.b.c
101a.b.c.d
102.Ed
103.Pp
104Any of the above four forms may have
105.Dq Li /bits
106appended where
107.Dq Li bits
108is in the range
109.Li 0-32
110and is used to explicitly specify the number of bits in the network address.
111When
112.Dq Li /bits
113is not specified the number of bits in the network address is calculated
114as the larger of the number of bits in the class to which the address
115belongs and the number of bits provided rounded up modulo 8.
116Examples:
117.Pp
118.Bl -tag -width 10.1.2.3/24 -offset indent -compact
119.It Li 10
120an 8-bit network number (class A), value
121.Li 10.0.0.0 .
122.It Li 192
123a 24-bit network number (class C), value
124.Li 192.0.0.0 .
125.It Li 10.10
126a 16-bit network number, value
127.Li 10.10.0.0 .
128.It Li 10.1.2
129a 24-bit network number, value
130.Li 10.1.2.0 .
131.It Li 10.1.2.3
132a 32-bit network number, value
133.Li 10.1.2.3 .
134.It Li 10.1.2.3/24
135a 24-bit network number (explicit), value
136.Li 10.1.2.3 .
137.El
138.Pp
139Note that when the number of bits is specified using
140.Dq Li /bits
141notation, the value of the address still includes all bits supplied
142in the external representation, even those bits which are the host
143part of an Internet address.
144Also, unlike
145.Xr inet_pton 3
146where the external representation is assumed to be a host address, the
147external representation for
148.Fn inet_net_pton
149is assumed to be a network address.
150Thus
151.Dq Li 10.1
152is assumed to be
153.Dq Li 10.1.0.0
154not
155.Dq Li 10.0.0.1
156.Pp
157All numbers supplied as
158.Dq parts
159in a
160.Ql \&.
161notation
162may be decimal, octal, or hexadecimal, as specified
163in the C language (i.e., a leading 0x or 0X implies
164hexadecimal; otherwise, a leading 0 implies octal;
165otherwise, the number is interpreted as decimal).
166.Sh SEE ALSO
167.Xr byteorder 3 ,
168.Xr inet 3 ,
169.Xr inet_pton 3 ,
170.Xr networks 5
171.Sh HISTORY
172The
173.Nm inet_net_ntop
174and
175.Nm inet_net_pton
176functions 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..fc9071798a
--- /dev/null
+++ b/src/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,135 @@
1/* $OpenBSD: inet_net_ntop.c,v 1.6 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#include <stdlib.h>
29
30static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t);
31
32/*
33 * char *
34 * inet_net_ntop(af, src, bits, dst, size)
35 * convert network number from network to presentation format.
36 * generates CIDR style result always.
37 * return:
38 * pointer to dst, or NULL if an error occurred (check errno).
39 * author:
40 * Paul Vixie (ISC), July 1996
41 */
42char *
43inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
44{
45 switch (af) {
46 case AF_INET:
47 return (inet_net_ntop_ipv4(src, bits, dst, size));
48 default:
49 errno = EAFNOSUPPORT;
50 return (NULL);
51 }
52}
53
54/*
55 * static char *
56 * inet_net_ntop_ipv4(src, bits, dst, size)
57 * convert IPv4 network number from network to presentation format.
58 * generates CIDR style result always.
59 * return:
60 * pointer to dst, or NULL if an error occurred (check errno).
61 * note:
62 * network byte order assumed. this means 192.5.5.240/28 has
63 * 0x11110000 in its fourth octet.
64 * author:
65 * Paul Vixie (ISC), July 1996
66 */
67static char *
68inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
69{
70 char *odst = dst;
71 u_int m;
72 int b;
73 char *ep;
74 int advance;
75
76 ep = dst + size;
77 if (ep <= dst)
78 goto emsgsize;
79
80 if (bits < 0 || bits > 32) {
81 errno = EINVAL;
82 return (NULL);
83 }
84 if (bits == 0) {
85 if (ep - dst < sizeof "0")
86 goto emsgsize;
87 *dst++ = '0';
88 *dst = '\0';
89 }
90
91 /* Format whole octets. */
92 for (b = bits / 8; b > 0; b--) {
93 if (ep - dst < sizeof "255.")
94 goto emsgsize;
95 advance = snprintf(dst, ep - dst, "%u", *src++);
96 if (advance <= 0 || advance >= ep - dst)
97 goto emsgsize;
98 dst += advance;
99 if (b > 1) {
100 if (dst + 1 >= ep)
101 goto emsgsize;
102 *dst++ = '.';
103 *dst = '\0';
104 }
105 }
106
107 /* Format partial octet. */
108 b = bits % 8;
109 if (b > 0) {
110 if (ep - dst < sizeof ".255")
111 goto emsgsize;
112 if (dst != odst)
113 if (dst + 1 >= ep)
114 goto emsgsize;
115 *dst++ = '.';
116 m = ((1 << b) - 1) << (8 - b);
117 advance = snprintf(dst, ep - dst, "%u", *src & m);
118 if (advance <= 0 || advance >= ep - dst)
119 goto emsgsize;
120 dst += advance;
121 }
122
123 /* Format CIDR /width. */
124 if (ep - dst < sizeof "/32")
125 goto emsgsize;
126 advance = snprintf(dst, ep - dst, "/%u", bits);
127 if (advance <= 0 || advance >= ep - dst)
128 goto emsgsize;
129 dst += advance;
130 return (odst);
131
132 emsgsize:
133 errno = EMSGSIZE;
134 return (NULL);
135}
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..3105c33b43
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,191 @@
1/* $OpenBSD: inet_net_pton.c,v 1.6 2008/09/01 09:40:43 markus 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 <assert.h>
26#include <ctype.h>
27#include <errno.h>
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31
32static int inet_net_pton_ipv4(const char *, u_char *, size_t);
33
34/*
35 * static int
36 * inet_net_pton(af, src, dst, size)
37 * convert network number from presentation to network format.
38 * accepts hex octets, hex strings, decimal octets, and /CIDR.
39 * "size" is in bytes and describes "dst".
40 * return:
41 * number of bits, either imputed classfully or specified with /CIDR,
42 * or -1 if some failure occurred (check errno). ENOENT means it was
43 * not a valid network specification.
44 * author:
45 * Paul Vixie (ISC), June 1996
46 */
47int
48inet_net_pton(int af, const char *src, void *dst, size_t size)
49{
50 switch (af) {
51 case AF_INET:
52 return (inet_net_pton_ipv4(src, dst, size));
53 default:
54 errno = EAFNOSUPPORT;
55 return (-1);
56 }
57}
58
59/*
60 * static int
61 * inet_net_pton_ipv4(src, dst, size)
62 * convert IPv4 network number from presentation to network format.
63 * accepts hex octets, hex strings, decimal octets, and /CIDR.
64 * "size" is in bytes and describes "dst".
65 * return:
66 * number of bits, either imputed classfully or specified with /CIDR,
67 * or -1 if some failure occurred (check errno). ENOENT means it was
68 * not an IPv4 network specification.
69 * note:
70 * network byte order assumed. this means 192.5.5.240/28 has
71 * 0x11110000 in its fourth octet.
72 * author:
73 * Paul Vixie (ISC), June 1996
74 */
75static int
76inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
77{
78 static const char
79 xdigits[] = "0123456789abcdef",
80 digits[] = "0123456789";
81 int n, ch, tmp, dirty, bits;
82 const u_char *odst = dst;
83
84 ch = *src++;
85 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
86 && isascii(src[1]) && isxdigit(src[1])) {
87 /* Hexadecimal: Eat nybble string. */
88 if (size <= 0)
89 goto emsgsize;
90 *dst = 0, dirty = 0;
91 src++; /* skip x or X. */
92 while ((ch = *src++) != '\0' &&
93 isascii(ch) && isxdigit(ch)) {
94 if (isupper(ch))
95 ch = tolower(ch);
96 n = strchr(xdigits, ch) - xdigits;
97 assert(n >= 0 && n <= 15);
98 *dst |= n;
99 if (!dirty++)
100 *dst <<= 4;
101 else if (size-- > 0)
102 *++dst = 0, dirty = 0;
103 else
104 goto emsgsize;
105 }
106 if (dirty)
107 size--;
108 } else if (isascii(ch) && isdigit(ch)) {
109 /* Decimal: eat dotted digit string. */
110 for (;;) {
111 tmp = 0;
112 do {
113 n = strchr(digits, ch) - digits;
114 assert(n >= 0 && n <= 9);
115 tmp *= 10;
116 tmp += n;
117 if (tmp > 255)
118 goto enoent;
119 } while ((ch = *src++) != '\0' &&
120 isascii(ch) && isdigit(ch));
121 if (size-- <= 0)
122 goto emsgsize;
123 *dst++ = (u_char) tmp;
124 if (ch == '\0' || ch == '/')
125 break;
126 if (ch != '.')
127 goto enoent;
128 ch = *src++;
129 if (!isascii(ch) || !isdigit(ch))
130 goto enoent;
131 }
132 } else
133 goto enoent;
134
135 bits = -1;
136 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
137 /* CIDR width specifier. Nothing can follow it. */
138 ch = *src++; /* Skip over the /. */
139 bits = 0;
140 do {
141 n = strchr(digits, ch) - digits;
142 assert(n >= 0 && n <= 9);
143 bits *= 10;
144 bits += n;
145 if (bits > 32)
146 goto emsgsize;
147 } while ((ch = *src++) != '\0' &&
148 isascii(ch) && isdigit(ch));
149 if (ch != '\0')
150 goto enoent;
151 }
152
153 /* Firey death and destruction unless we prefetched EOS. */
154 if (ch != '\0')
155 goto enoent;
156
157 /* If nothing was written to the destination, we found no address. */
158 if (dst == odst)
159 goto enoent;
160 /* If no CIDR spec was given, infer width from net class. */
161 if (bits == -1) {
162 if (*odst >= 240) /* Class E */
163 bits = 32;
164 else if (*odst >= 224) /* Class D */
165 bits = 4;
166 else if (*odst >= 192) /* Class C */
167 bits = 24;
168 else if (*odst >= 128) /* Class B */
169 bits = 16;
170 else /* Class A */
171 bits = 8;
172 /* If imputed mask is narrower than specified octets, widen. */
173 if (bits < ((dst - odst) * 8))
174 bits = (dst - odst) * 8;
175 }
176 /* Extend network to cover the actual mask. */
177 while (bits > ((dst - odst) * 8)) {
178 if (size-- <= 0)
179 goto emsgsize;
180 *dst++ = '\0';
181 }
182 return (bits);
183
184 enoent:
185 errno = ENOENT;
186 return (-1);
187
188 emsgsize:
189 errno = EMSGSIZE;
190 return (-1);
191}
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 */
40char *
41inet_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
38static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_netof.c,v 1.4 1995/02/25 06:20:43 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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 */
52u_long 39in_addr_t
53inet_netof(in) 40inet_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..8b26ba8ff9 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.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,14 +28,6 @@
33 * SUCH DAMAGE. 28 * SUCH DAMAGE.
34 */ 29 */
35 30
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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 */
54u_long 41in_addr_t
55inet_network(cp) 42inet_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 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
63again: 49again:
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
38static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: inet_ntoa.c,v 1.4 1995/02/25 06:20:46 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
53char * 40char *
54inet_ntoa(in) 41inet_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 *)&in; 46 p = (char *)&in;
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..d36a0d7889
--- /dev/null
+++ b/src/lib/libc/net/inet_ntop.c
@@ -0,0 +1,195 @@
1/* $OpenBSD: inet_ntop.c,v 1.7 2005/08/06 20:30:03 espie 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
34static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
35static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
36
37/* 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 */
45const char *
46inet_ntop(int af, const void *src, char *dst, size_t size)
47{
48 switch (af) {
49 case AF_INET:
50 return (inet_ntop4(src, dst, size));
51 case AF_INET6:
52 return (inet_ntop6(src, dst, 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 */
71static const char *
72inet_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 */
93static const char *
94inet_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 return (NULL);
153 *tp++ = ':';
154 }
155 continue;
156 }
157 /* Are we following an initial run of 0x00s or any real hex? */
158 if (i != 0) {
159 if (tp + 1 >= ep)
160 return (NULL);
161 *tp++ = ':';
162 }
163 /* Is this address an encapsulated IPv4? */
164 if (i == 6 && best.base == 0 &&
165 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
166 if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
167 return (NULL);
168 tp += strlen(tp);
169 break;
170 }
171 advance = snprintf(tp, ep - tp, "%x", words[i]);
172 if (advance <= 0 || advance >= ep - tp)
173 return (NULL);
174 tp += advance;
175 }
176 /* Was it a trailing run of 0x00's? */
177 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
178 if (tp + 1 >= ep)
179 return (NULL);
180 *tp++ = ':';
181 }
182 if (tp + 1 >= ep)
183 return (NULL);
184 *tp++ = '\0';
185
186 /*
187 * Check for overflow, copy, and we're done.
188 */
189 if ((size_t)(tp - tmp) > size) {
190 errno = ENOSPC;
191 return (NULL);
192 }
193 strlcpy(dst, tmp, size);
194 return (dst);
195}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..096ff65772
--- /dev/null
+++ b/src/lib/libc/net/inet_pton.c
@@ -0,0 +1,212 @@
1/* $OpenBSD: inet_pton.c,v 1.7 2006/12/30 23:37:37 itojun Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#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
33static int inet_pton4(const char *src, u_char *dst);
34static 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 */
47int
48inet_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 */
72static int
73inet_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 * (1) does not touch `dst' unless it's returning 1.
118 * (2) :: in a full address is silently ignored.
119 * credit:
120 * inspired by Mark Andrews.
121 * author:
122 * Paul Vixie, 1996.
123 */
124static int
125inet_pton6(const char *src, u_char *dst)
126{
127 static const char xdigits_l[] = "0123456789abcdef",
128 xdigits_u[] = "0123456789ABCDEF";
129 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
130 const char *xdigits, *curtok;
131 int ch, saw_xdigit, count_xdigit;
132 u_int val;
133
134 memset((tp = tmp), '\0', IN6ADDRSZ);
135 endp = tp + IN6ADDRSZ;
136 colonp = NULL;
137 /* Leading :: requires some special handling. */
138 if (*src == ':')
139 if (*++src != ':')
140 return (0);
141 curtok = src;
142 saw_xdigit = count_xdigit = 0;
143 val = 0;
144 while ((ch = *src++) != '\0') {
145 const char *pch;
146
147 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
148 pch = strchr((xdigits = xdigits_u), ch);
149 if (pch != NULL) {
150 if (count_xdigit >= 4)
151 return (0);
152 val <<= 4;
153 val |= (pch - xdigits);
154 if (val > 0xffff)
155 return (0);
156 saw_xdigit = 1;
157 count_xdigit++;
158 continue;
159 }
160 if (ch == ':') {
161 curtok = src;
162 if (!saw_xdigit) {
163 if (colonp)
164 return (0);
165 colonp = tp;
166 continue;
167 } else if (*src == '\0') {
168 return (0);
169 }
170 if (tp + INT16SZ > endp)
171 return (0);
172 *tp++ = (u_char) (val >> 8) & 0xff;
173 *tp++ = (u_char) val & 0xff;
174 saw_xdigit = 0;
175 count_xdigit = 0;
176 val = 0;
177 continue;
178 }
179 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
180 inet_pton4(curtok, tp) > 0) {
181 tp += INADDRSZ;
182 saw_xdigit = 0;
183 count_xdigit = 0;
184 break; /* '\0' was seen by inet_pton4(). */
185 }
186 return (0);
187 }
188 if (saw_xdigit) {
189 if (tp + INT16SZ > endp)
190 return (0);
191 *tp++ = (u_char) (val >> 8) & 0xff;
192 *tp++ = (u_char) val & 0xff;
193 }
194 if (colonp != NULL) {
195 /*
196 * Since some memmove()'s erroneously fail to handle
197 * overlapping regions, we'll do the shift by hand.
198 */
199 const int n = tp - colonp;
200 int i;
201
202 for (i = 1; i <= n; i++) {
203 endp[- i] = colonp[n - i];
204 colonp[n - i] = 0;
205 }
206 tp = endp;
207 }
208 if (tp != endp)
209 return (0);
210 memcpy(dst, tmp, IN6ADDRSZ);
211 return (1);
212}
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c
new file mode 100644
index 0000000000..b215f9ac3e
--- /dev/null
+++ b/src/lib/libc/net/ip6opt.c
@@ -0,0 +1,596 @@
1/* $OpenBSD: ip6opt.c,v 1.4 2006/12/09 01:12:28 itojun 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
43static int ip6optlen(u_int8_t *opt, u_int8_t *lim);
44static 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 */
55int
56inet6_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 */
67int
68inet6_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 */
94int
95inet6_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 */
168u_int8_t *
169inet6_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 */
231int
232inet6_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 */
287int
288inet6_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 */
340static int
341ip6optlen(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
359static void
360inet6_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
381int
382inet6_opt_init(void *extbuf, socklen_t extlen)
383{
384 struct ip6_ext *ext = (struct ip6_ext *)extbuf;
385
386 if (extlen < 0 || (extlen % 8))
387 return (-1);
388
389 if (ext) {
390 if (extlen == 0)
391 return (-1);
392 ext->ip6e_len = (extlen >> 3) - 1;
393 }
394
395 return (2); /* sizeof the next and the length fields */
396}
397
398int
399inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
400 socklen_t len, u_int8_t align, void **databufp)
401{
402 int currentlen = offset, padlen = 0;
403
404 /*
405 * The option type must have a value from 2 to 255, inclusive.
406 * (0 and 1 are reserved for the Pad1 and PadN options, respectively.)
407 */
408#if 0 /* always false */
409 if (type < 2 || type > 255)
410#else
411 if (type < 2)
412#endif
413 return (-1);
414
415 /*
416 * The option data length must have a value between 0 and 255,
417 * inclusive, and is the length of the option data that follows.
418 */
419 if (len < 0 || len > 255)
420 return (-1);
421
422 /*
423 * The align parameter must have a value of 1, 2, 4, or 8.
424 * The align value can not exceed the value of len.
425 */
426 if (align != 1 && align != 2 && align != 4 && align != 8)
427 return (-1);
428 if (align > len)
429 return (-1);
430
431 /* Calculate the padding length. */
432 currentlen += 2 + len; /* 2 means "type + len" */
433 if (currentlen % align)
434 padlen = align - (currentlen % align);
435
436 /* The option must fit in the extension header buffer. */
437 currentlen += padlen;
438 if (extlen && /* XXX: right? */
439 currentlen > extlen)
440 return (-1);
441
442 if (extbuf) {
443 u_int8_t *optp = (u_int8_t *)extbuf + offset;
444
445 if (padlen == 1) {
446 /* insert a Pad1 option */
447 *optp = IP6OPT_PAD1;
448 optp++;
449 } else if (padlen > 0) {
450 /* insert a PadN option for alignment */
451 *optp++ = IP6OPT_PADN;
452 *optp++ = padlen - 2;
453 memset(optp, 0, padlen - 2);
454 optp += (padlen - 2);
455 }
456
457 *optp++ = type;
458 *optp++ = len;
459
460 *databufp = optp;
461 }
462
463 return (currentlen);
464}
465
466int
467inet6_opt_finish(void *extbuf, socklen_t extlen, int offset)
468{
469 int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0;;
470
471 if (extbuf) {
472 u_int8_t *padp;
473 int padlen = updatelen - offset;
474
475 if (updatelen > extlen)
476 return (-1);
477
478 padp = (u_int8_t *)extbuf + offset;
479 if (padlen == 1)
480 *padp = IP6OPT_PAD1;
481 else if (padlen > 0) {
482 *padp++ = IP6OPT_PADN;
483 *padp++ = (padlen - 2);
484 memset(padp, 0, padlen - 2);
485 }
486 }
487
488 return (updatelen);
489}
490
491int
492inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen)
493{
494
495 memcpy((u_int8_t *)databuf + offset, val, vallen);
496 return (offset + vallen);
497}
498
499int
500inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep,
501 socklen_t *lenp, void **databufp)
502{
503 u_int8_t *optp, *lim;
504 int optlen;
505
506 /* Validate extlen. XXX: is the variable really necessary?? */
507 if (extlen == 0 || (extlen % 8))
508 return (-1);
509 lim = (u_int8_t *)extbuf + extlen;
510
511 /*
512 * If this is the first time this function called for this options
513 * header, simply return the 1st option.
514 * Otherwise, search the option list for the next option.
515 */
516 if (offset == 0)
517 optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
518 else
519 optp = (u_int8_t *)extbuf + offset;
520
521 /* Find the next option skipping any padding options. */
522 while (optp < lim) {
523 switch(*optp) {
524 case IP6OPT_PAD1:
525 optp++;
526 break;
527 case IP6OPT_PADN:
528 if ((optlen = ip6optlen(optp, lim)) == 0)
529 goto optend;
530 optp += optlen;
531 break;
532 default: /* found */
533 if ((optlen = ip6optlen(optp, lim)) == 0)
534 goto optend;
535 *typep = *optp;
536 *lenp = optlen - 2;
537 *databufp = optp + 2;
538 return (optp + optlen - (u_int8_t *)extbuf);
539 }
540 }
541
542 optend:
543 *databufp = NULL; /* for safety */
544 return (-1);
545}
546
547int
548inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
549 socklen_t *lenp, void **databufp)
550{
551 u_int8_t *optp, *lim;
552 int optlen;
553
554 /* Validate extlen. XXX: is the variable really necessary?? */
555 if (extlen == 0 || (extlen % 8))
556 return (-1);
557 lim = (u_int8_t *)extbuf + extlen;
558
559 /*
560 * If this is the first time this function called for this options
561 * header, simply return the 1st option.
562 * Otherwise, search the option list for the next option.
563 */
564 if (offset == 0)
565 optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
566 else
567 optp = (u_int8_t *)extbuf + offset;
568
569 /* Find the specified option */
570 while (optp < lim) {
571 if ((optlen = ip6optlen(optp, lim)) == 0)
572 goto optend;
573
574 if (*optp == type) { /* found */
575 *lenp = optlen - 2;
576 *databufp = optp + 2;
577 return (optp + optlen - (u_int8_t *)extbuf);
578 }
579
580 optp += optlen;
581 }
582
583 optend:
584 *databufp = NULL; /* for safety */
585 return (-1);
586}
587
588int
589inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen)
590{
591
592 /* we can't assume alignment here */
593 memcpy(val, (u_int8_t *)databuf + offset, vallen);
594
595 return (offset + vallen);
596}
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
51The routine
52.Fn iso_addr
53interprets character strings representing
54.Tn OSI
55addresses, returning binary information suitable
56for use in system calls.
57The routine
58.Fn iso_ntoa
59takes
60.Tn OSI
61addresses and returns
62.Tn ASCII
63strings representing NSAPs (network service
64access points) in a
65notation inverse to that accepted by
66.Fn iso_addr .
67.Pp
68Unfortunately, no universal standard exists for representing
69.Tn OSI
70network addresses.
71.Pp
72The format employed by
73.Fn iso_addr
74is a sequence of hexadecimal
75.Dq digits
76(optionally separated by periods),
77of the form:
78.Bd -filled -offset indent
79<hex digits>.<hex digits>.<hex digits>
80.Ed
81.Pp
82Each pair of hexadecimal digits represents a byte
83with the leading digit indicating the higher-ordered bits.
84A period following an even number of bytes has no
85effect (but may be used to increase legibility).
86A period following an odd number of bytes has the
87effect of causing the byte of address being translated
88to have its higher order bits filled with zeros.
89.Sh RETURN VALUES
90.Fn iso_ntoa
91always returns a null terminated string.
92.Fn iso_addr
93always returns a pointer to a struct iso_addr.
94(See
95.Sx BUGS . )
96.Sh SEE ALSO
97.Xr iso 4
98.Sh HISTORY
99The
100.Fn iso_addr
101and
102.Fn iso_ntoa
103functions appeared in
104.Bx 4.3 Reno .
105.Sh BUGS
106The returned values
107reside in a static memory area.
108.Pp
109The function
110.Fn iso_addr
111should diagnose improperly formed input, and there should be an unambiguous
112way 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
38static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: iso_addr.c,v 1.4 1995/02/25 06:20:47 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
57struct iso_addr *
58iso_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}
99static char hexlist[] = "0123456789abcdef";
100
101char *
102iso_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..e6210ef2d0 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.12 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1993 3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -14,11 +14,7 @@
14.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
17.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
18.\" must display the following acknowledgement:
19.\" This product includes software developed by the University of
20.\" California, Berkeley and its contributors.
21.\" 4. Neither the name of the University nor the names of its contributors
22.\" may be used to endorse or promote products derived from this software 18.\" may be used to endorse or promote products derived from this software
23.\" without specific prior written permission. 19.\" without specific prior written permission.
24.\" 20.\"
@@ -34,11 +30,9 @@
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
36.\" 32.\"
37.\" @(#)linkaddr.3 8.1 (Berkeley) 7/28/93 33.Dd $Mdocdate: May 31 2007 $
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
@@ -52,12 +46,11 @@
52.Ft char * 46.Ft char *
53.Fn link_ntoa "const struct sockaddr_dl *sdl" 47.Fn link_ntoa "const struct sockaddr_dl *sdl"
54.Sh DESCRIPTION 48.Sh DESCRIPTION
55The routine 49The
56.Fn link_addr 50.Fn link_addr
57interprets character strings representing 51function interprets character strings representing
58link-level addresses, returning binary information suitable 52link-level addresses, returning binary information suitable
59for use in system calls. 53for use in system calls.
60The routine
61.Fn link_ntoa 54.Fn link_ntoa
62takes 55takes
63a link-level 56a link-level
@@ -75,9 +68,9 @@ the string
75.Fa addr 68.Fa addr
76may contain 69may contain
77an optional network interface identifier of the form 70an optional network interface identifier of the form
78.Dq "name unit-number" , 71.Dq name unit-number ,
79suitable for the first argument to 72suitable for the first argument to
80.Xr ifconfig 4 , 73.Xr ifconfig 8 ,
81followed in all cases by a colon and 74followed in all cases by a colon and
82an interface address in the form of 75an interface address in the form of
83groups of hexadecimal digits 76groups of hexadecimal digits
@@ -93,26 +86,27 @@ low order bytes through high order bytes.
93.\" .Pp 86.\" .Pp
94Thus 87Thus
95.Li le0:8.0.9.13.d.30 88.Li le0:8.0.9.13.d.30
96represents an ethernet address 89represents an Ethernet address
97to be transmitted on the first Lance ethernet interface. 90to be transmitted on the first Lance Ethernet interface.
98.Sh RETURN VALUES 91.Sh RETURN VALUES
99.Fn link_ntoa 92.Fn link_ntoa
100always returns a null terminated string. 93always returns a NUL-terminated string.
101.Fn link_addr 94.Fn link_addr
102has no return value. 95has no return value.
103(See 96(See
104.Sx BUGS . ) 97.Sx BUGS . )
105.Sh SEE ALSO 98.Sh SEE ALSO
106.Xr iso 4 , 99.Xr ifconfig 8
107.Sh HISTORY 100.Sh HISTORY
108The 101The
109.Fn link_addr 102.Fn link_addr
110and 103and
111.Fn link_ntoa 104.Fn link_ntoa
112functions appeared in 105functions appeared in
113.Bx 4.3 Reno . 106.Bx 4.3 Reno .
114.Sh BUGS 107.Sh BUGS
115The returned values for link_ntoa 108The returned values for
109.Fn link_ntoa
116reside in a static memory area. 110reside in a static memory area.
117.Pp 111.Pp
118The function 112The function
@@ -121,7 +115,7 @@ should diagnose improperly formed input, and there should be an unambiguous
121way to recognize this. 115way to recognize this.
122.Pp 116.Pp
123If the 117If the
124.Va sdl_len 118.Fa sdl_len
125field of the link socket address 119field of the link socket address
126.Fa sdl 120.Fa sdl
127is 0, 121is 0,
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c
index 19a0de3abd..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
38static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: linkaddr.c,v 1.5 1995/02/25 06:20:49 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
60void 47void
61link_addr(addr, sdl) 48link_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)
129static char hexlist[] = "0123456789abcdef"; 114static char hexlist[] = "0123456789abcdef";
130 115
131char * 116char *
132link_ntoa(sdl) 117link_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/net_addrcmp.3 b/src/lib/libc/net/net_addrcmp.3
new file mode 100644
index 0000000000..a02e6e2619
--- /dev/null
+++ b/src/lib/libc/net/net_addrcmp.3
@@ -0,0 +1,91 @@
1.\" $OpenBSD: net_addrcmp.3,v 1.4 2007/05/31 19:19:30 jmc Exp $
2.\"
3.\" Copyright (c) 1999 Theo de Raadt
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\"
14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\"
25.Dd $Mdocdate: May 31 2007 $
26.Dt NET_ADDRCMP 3
27.Os
28.Sh NAME
29.Nm net_addrcmp
30.Nd compare socket address structures
31.Sh SYNOPSIS
32.Fd #include <netdb.h>
33.Ft int
34.Fn net_addrcmp "struct sockaddr *sa1" "struct sockaddr *sa2"
35.Sh DESCRIPTION
36The
37.Fn net_addrcmp
38function compares two socket address structures,
39.Fa sa1
40and
41.Fa sa2 .
42.Sh RETURN VALUES
43If
44.Fa sa1
45and
46.Fa sa2
47are for the same address,
48.Fn net_addrcmp
49returns 0.
50.Pp
51The
52.Fa sa_len
53fields are compared first.
54If they do not match,
55.Fn net_addrcmp
56returns \-1 or 1 if
57.Li sa1->sa_len
58is less than or greater than
59.Li sa2->sa_len ,
60respectively.
61.Pp
62Next, the
63.Fa sa_family
64members are compared.
65If they do not match,
66.Fn net_addrcmp
67returns \-1 or 1 if
68.Li sa1->sa_family
69is less than or greater than
70.Li sa2->sa_family ,
71respectively.
72.Pp
73Lastly, if each socket address structure's
74.Fa sa_len
75and
76.Fa sa_family
77fields match,
78the protocol-specific data (the
79.Fa sa_data
80field) is compared.
81If there's a match, both
82.Fa sa1
83and
84.Fa sa2
85must refer to the same address, and 0 is returned; otherwise, a value >0
86or <0 is returned.
87.Sh HISTORY
88A
89.Fn net_addrcmp
90function was added in
91.Ox 2.5 .
diff --git a/src/lib/libc/net/net_addrcmp.c b/src/lib/libc/net/net_addrcmp.c
new file mode 100644
index 0000000000..c2630a5265
--- /dev/null
+++ b/src/lib/libc/net/net_addrcmp.c
@@ -0,0 +1,63 @@
1/* $OpenBSD: net_addrcmp.c,v 1.10 2005/06/17 20:36:16 henning Exp $ */
2
3/*
4 * Copyright (c) 1999 Theo de Raadt
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 BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT 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 OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/un.h>
31#include <netinet/in.h>
32#include <string.h>
33
34int
35net_addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
36{
37
38 if (sa1->sa_len != sa2->sa_len)
39 return (sa1->sa_len < sa2->sa_len) ? -1 : 1;
40 if (sa1->sa_family != sa2->sa_family)
41 return (sa1->sa_family < sa2->sa_family) ? -1 : 1;
42
43 switch(sa1->sa_family) {
44 case AF_INET:
45 return (memcmp(&((struct sockaddr_in *)sa1)->sin_addr,
46 &((struct sockaddr_in *)sa2)->sin_addr,
47 sizeof(struct in_addr)));
48 case AF_INET6:
49 if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
50 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
51 return (((struct sockaddr_in6 *)sa1)->sin6_scope_id <
52 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
53 ? -1 : 1;
54 return memcmp(&((struct sockaddr_in6 *)sa1)->sin6_addr,
55 &((struct sockaddr_in6 *)sa2)->sin6_addr,
56 sizeof(struct in6_addr));
57 case AF_LOCAL:
58 return (strcmp(((struct sockaddr_un *)sa1)->sun_path,
59 ((struct sockaddr_un *)sa1)->sun_path));
60 default:
61 return -1;
62 }
63}
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)
44address 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
53The routine
54.Fn ns_addr
55interprets character strings representing
56.Tn XNS
57addresses, returning binary information suitable
58for use in system calls.
59The routine
60.Fn ns_ntoa
61takes
62.Tn XNS
63addresses and returns
64.Tn ASCII
65strings representing the address in a
66notation in common use in the Xerox Development Environment:
67.Bd -filled -offset indent
68<network number>.<host number>.<port number>
69.Ed
70.Pp
71Trailing zero fields are suppressed, and each number is printed in hexadecimal,
72in a format suitable for input to
73.Fn ns_addr .
74Any fields lacking super-decimal digits will have a
75trailing
76.Ql H
77appended.
78.Pp
79Unfortunately, no universal standard exists for representing
80.Tn XNS
81addresses.
82An effort has been made to insure that
83.Fn ns_addr
84be compatible with most formats in common use.
85It will first separate an address into 1 to 3 fields using a single delimiter
86chosen from
87period
88.Ql \&. ,
89colon
90.Ql \&:
91or pound-sign
92.Ql \&# .
93Each field is then examined for byte separators (colon or period).
94If there are byte separators, each subfield separated is taken to be
95a small hexadecimal number, and the entirety is taken as a network-byte-ordered
96quantity to be zero extended in the high-network-order bytes.
97Next, the field is inspected for hyphens, in which case
98the field is assumed to be a number in decimal notation
99with hyphens separating the millenia.
100Next, the field is assumed to be a number:
101It is interpreted
102as hexadecimal if there is a leading
103.Ql 0x
104(as in C),
105a trailing
106.Ql H
107(as in Mesa), or there are any super-decimal digits present.
108It is interpreted as octal is there is a leading
109.Ql 0
110and there are no super-octal digits.
111Otherwise, it is converted as a decimal number.
112.Sh RETURN VALUES
113None. (See
114.Sx BUGS . )
115.Sh SEE ALSO
116.Xr hosts 5 ,
117.Xr networks 5 ,
118.Sh HISTORY
119The
120.Fn ns_addr
121and
122.Fn ns_toa
123functions appeared in
124.Bx 4.3 .
125.Sh BUGS
126The string returned by
127.Fn ns_ntoa
128resides in a static memory area.
129The function
130.Fn ns_addr
131should diagnose improperly formed input, and there should be an unambiguous
132way 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
41static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
42#else
43static char rcsid[] = "$NetBSD: ns_addr.c,v 1.5 1995/02/25 06:20:51 cgd Exp $";
44#endif
45#endif /* LIBC_SCCS and not lint */
46
47#include <sys/param.h>
48#include <netns/ns.h>
49#include <stdio.h>
50#include <string.h>
51
52static struct ns_addr addr, zero_addr;
53
54static void Field(), cvtbase();
55
56struct ns_addr
57ns_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
103static void
104Field(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
207static void
208cvtbase(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
38static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: ns_ntoa.c,v 1.4 1995/02/25 06:20:51 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <sys/param.h>
45#include <netns/ns.h>
46#include <stdio.h>
47
48char *
49ns_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
86static char *
87spectHex(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/nsap_addr.c b/src/lib/libc/net/nsap_addr.c
new file mode 100644
index 0000000000..8cfe86f475
--- /dev/null
+++ b/src/lib/libc/net/nsap_addr.c
@@ -0,0 +1,94 @@
1/* $OpenBSD: nsap_addr.c,v 1.7 2006/03/31 05:35:44 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <sys/param.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/nameser.h>
25#include <ctype.h>
26#include <resolv.h>
27
28static u_char
29xtob(int c)
30{
31 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
32}
33
34u_int
35inet_nsap_addr(const char *ascii, u_char *binary, int maxlen)
36{
37 u_char c, nib;
38 u_int len = 0;
39
40 while ((c = *ascii++) != '\0' && len < maxlen) {
41 if (c == '.' || c == '+' || c == '/')
42 continue;
43 if (!isascii(c))
44 return (0);
45 if (islower(c))
46 c = (u_char)toupper(c);
47 if (isxdigit(c)) {
48 nib = xtob(c);
49 if ((c = *ascii++)) {
50 c = (u_char)toupper(c);
51 if (isxdigit(c)) {
52 *binary++ = (nib << 4) | xtob(c);
53 len++;
54 } else
55 return (0);
56 }
57 else
58 return (0);
59 }
60 else
61 return (0);
62 }
63 return (len);
64}
65
66char *
67inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii)
68{
69 int nib;
70 int i;
71 static char tmpbuf[255*3];
72 char *start;
73
74 if (ascii)
75 start = ascii;
76 else {
77 ascii = tmpbuf;
78 start = tmpbuf;
79 }
80
81 if (binlen > 255)
82 binlen = 255;
83
84 for (i = 0; i < binlen; i++) {
85 nib = *binary >> 4;
86 *ascii++ = nib + (nib < 10 ? '0' : '7');
87 nib = *binary++ & 0x0f;
88 *ascii++ = nib + (nib < 10 ? '0' : '7');
89 if (((i % 2) == 0 && (i + 1) < binlen))
90 *ascii++ = '.';
91 }
92 *ascii = '\0';
93 return (start);
94}
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)
9static 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
17unsigned long 12u_int32_t
18ntohl(x) 13ntohl(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)
9static 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
17unsigned short 12u_int16_t
18ntohs(x) 13ntohs(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..87e9a760a8 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.27 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,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: May 31 2007 $
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.Fd #include <unistd.h>
47.Ft int 44.Ft int
48.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" 45.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
49.Ft int 46.Ft int
47.Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af"
48.Ft int
50.Fn rresvport "int *port" 49.Fn rresvport "int *port"
51.Ft int 50.Ft int
52.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" 51.Fn rresvport_af "int *port" "int af"
52.Ft int
53.Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser"
53.Ft int 54.Ft int
54.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" 55.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
56.Ft int
57.Fn iruserok_sa "const void *sa" "int salen" "int superuser" "const char *ruser" "const char *luser"
55.Sh DESCRIPTION 58.Sh DESCRIPTION
56The 59The
57.Fn rcmd 60.Fn rcmd
58function 61function is used by the superuser to execute a command on a remote
59is used by the super-user to execute a command on 62machine using an authentication scheme based on reserved
60a remote machine using an authentication scheme based 63port numbers.
61on reserved port numbers. 64If the calling process is not setuid, the
65.Ev RSH
66environment variable is set, and
67.Fa inport
68is
69.Dq shell/tcp ,
70.Xr rcmdsh 3
71is called instead with the value of
72.Ev RSH .
73Alternately, if the user is not the superuser,
74.Fn rcmd
75will invoke
76.Xr rcmdsh 3
77to run the command via
78.Xr rsh 1 .
79While
80.Fn rcmd
81can handle IPv4 cases only,
82the
83.Fn rcmd_af
84function can handle other cases as well.
85.Pp
62The 86The
63.Fn rresvport 87.Fn rresvport
64function 88and
65returns a descriptor to a socket 89.Fn rresvport_af
90functions return a descriptor to a socket
66with an address in the privileged port space. 91with an address in the privileged port space.
67The 92The
68.Fn iruserok 93.Fn iruserok
@@ -75,11 +100,13 @@ All four functions are present in the same file and are used
75by the 100by the
76.Xr rshd 8 101.Xr rshd 8
77server (among others). 102server (among others).
103.Fn iruserok_sa
104is an address family independent variant of
105.Fn iruserok .
78.Pp 106.Pp
79The 107The
80.Fn rcmd 108.Fn rcmd
81function 109function looks up the host
82looks up the host
83.Fa *ahost 110.Fa *ahost
84using 111using
85.Xr gethostbyname 3 , 112.Xr gethostbyname 3 ,
@@ -90,15 +117,15 @@ is set to the standard name of the host
90and a connection is established to a server 117and a connection is established to a server
91residing at the well-known Internet port 118residing at the well-known Internet port
92.Fa inport . 119.Fa inport .
120If the user is not the superuser, the only valid port is
121.Dq shell/tcp
122(usually port 514).
93.Pp 123.Pp
94If the connection succeeds, 124If the connection succeeds,
95a socket in the Internet domain of type 125a socket in the Internet domain of type
96.Dv SOCK_STREAM 126.Dv SOCK_STREAM
97is returned to the caller, and given to the remote 127is returned to the caller, and given to the remote
98command as 128command as stdin and stdout.
99.Em stdin
100and
101.Em stdout .
102If 129If
103.Fa fd2p 130.Fa fd2p
104is non-zero, then an auxiliary channel to a control 131is non-zero, then an auxiliary channel to a control
@@ -113,27 +140,46 @@ signal numbers, to be
113forwarded to the process group of the command. 140forwarded to the process group of the command.
114If 141If
115.Fa fd2p 142.Fa fd2p
116is 0, then the 143is
117.Em stderr 144.Va NULL ,
118(unit 2 of the remote 145then the standard error (unit 2 of the remote command) will be made
119command) will be made the same as the 146the same as the standard output and no provision is made for sending
120.Em stdout 147arbitrary signals to the remote process, although you may be able to
121and no 148get its attention by using out-of-band data.
122provision is made for sending arbitrary signals to the remote process, 149Note that if the user is not the superuser,
123although you may be able to get its attention by using out-of-band data. 150.Fa fd2p
151must be
152.Va NULL .
153.Pp
154.Fn rcmd_af
155takes address family in the last argument.
156If the last argument is
157.Dv PF_UNSPEC ,
158interpretation of
159.Fa *ahost
160will obey the underlying address resolution like DNS.
124.Pp 161.Pp
125The protocol is described in detail in 162The protocol is described in detail in
126.Xr rshd 8 . 163.Xr rshd 8 .
127.Pp 164.Pp
128The 165The
129.Fn rresvport 166.Fn rresvport
130function is used to obtain a socket with a privileged 167and
131address bound to it. This socket is suitable for use 168.Fn rresvport_af
132by 169functions are used to obtain a socket with a privileged
170address bound to it.
171This socket is suitable for use by
133.Fn rcmd 172.Fn rcmd
134and several other functions. Privileged Internet ports are those 173and several other functions.
135in the range 0 to 1023. Only the super-user 174Privileged Internet ports are those in the range 0 to
136is allowed to bind an address of this sort to a socket. 175.Va IPPORT_RESERVED - 1 ,
176which happens to be 1023.
177Only the superuser is allowed to bind an address of this sort to a socket.
178.Fn rresvport
179and
180.Fn rresvport_af
181need to be seeded with a port number; if that port
182is not available these functions will find another.
137.Pp 183.Pp
138The 184The
139.Fn iruserok 185.Fn iruserok
@@ -141,10 +187,10 @@ and
141.Fn ruserok 187.Fn ruserok
142functions take a remote host's IP address or name, respectively, 188functions take a remote host's IP address or name, respectively,
143two user names and a flag indicating whether the local user's 189two user names and a flag indicating whether the local user's
144name is that of the super-user. 190name is that of the superuser.
145Then, if the user is 191Then, if the user is
146.Em NOT 192.Em not
147the super-user, it checks the 193the superuser, it checks the
148.Pa /etc/hosts.equiv 194.Pa /etc/hosts.equiv
149file. 195file.
150If that lookup is not done, or is unsuccessful, the 196If that lookup is not done, or is unsuccessful, the
@@ -153,19 +199,19 @@ in the local user's home directory is checked to see if the request for
153service is allowed. 199service is allowed.
154.Pp 200.Pp
155If this file does not exist, is not a regular file, is owned by anyone 201If this file does not exist, is not a regular file, is owned by anyone
156other than the user or the super-user, or is writeable by anyone other 202other than the user or the superuser, or is writeable by anyone other
157than the owner, the check automatically fails. 203than the owner, the check automatically fails.
158Zero is returned if the machine name is listed in the 204Zero is returned if the machine name is listed in the
159.Dq Pa hosts.equiv 205.Pa hosts.equiv
160file, or the host and remote user name are found in the 206file, or the host and remote user name are found in the
161.Dq Pa .rhosts 207.Pa .rhosts
162file; otherwise 208file; otherwise
163.Fn iruserok 209.Fn iruserok
164and 210and
165.Fn ruserok 211.Fn ruserok
166return \-1. 212return \-1.
167If the local domain (as obtained from 213If the local domain (as obtained from
168.Xr gethostname 2 ) 214.Xr gethostname 3 )
169is the same as the remote domain, only the machine name need be specified. 215is the same as the remote domain, only the machine name need be specified.
170.Pp 216.Pp
171If the IP address of the remote host is known, 217If the IP address of the remote host is known,
@@ -173,32 +219,48 @@ If the IP address of the remote host is known,
173should be used in preference to 219should be used in preference to
174.Fn ruserok , 220.Fn ruserok ,
175as it does not require trusting the DNS server for the remote host's domain. 221as it does not require trusting the DNS server for the remote host's domain.
222.Pp
223While
224.Fn iruserok
225can handle IPv4 addresses only,
226.Fn iruserok_sa
227and
228.Fn ruserok
229can handle other address families as well, like IPv6.
230The first argument of
231.Fn iruserok_sa
232is typed as
233.Li "void *"
234to avoid dependency between
235.Aq Pa unistd.h
236and
237.Aq Pa sys/socket.h .
176.Sh DIAGNOSTICS 238.Sh DIAGNOSTICS
177The 239The
178.Fn rcmd 240.Fn rcmd
179function 241function returns a valid socket descriptor on success.
180returns a valid socket descriptor on success.
181It returns \-1 on error and prints a diagnostic message on the standard error. 242It returns \-1 on error and prints a diagnostic message on the standard error.
182.Pp 243.Pp
183The 244The
184.Fn rresvport 245.Fn rresvport
185function 246and
186returns a valid, bound socket descriptor on success. 247.Fn rresvport_af
248functions return a valid, bound socket descriptor on success.
187It returns \-1 on error with the global value 249It returns \-1 on error with the global value
188.Va errno 250.Va errno
189set according to the reason for failure. 251set according to the reason for failure.
190The error code 252The error code
191.Dv EAGAIN 253.Er EAGAIN
192is overloaded to mean ``All network ports in use.'' 254is overloaded to mean
255.Dq all network ports in use .
193.Sh SEE ALSO 256.Sh SEE ALSO
194.Xr rlogin 1 ,
195.Xr rsh 1 , 257.Xr rsh 1 ,
196.Xr intro 2 , 258.Xr intro 2 ,
197.Xr rexec 3 , 259.Xr bindresvport 3 ,
198.Xr rexecd 8 , 260.Xr bindresvport_sa 3 ,
199.Xr rlogind 8 , 261.Xr rcmdsh 3 ,
200.Xr rshd 8 262.Xr rshd 8
201.Sh HISTORY 263.Sh HISTORY
202These 264These
203functions appeared in 265functions appeared in
204.Bx 4.2 . 266.Bx 4.2 .
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c
index e0310031b0..30ca6710c4 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
38static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
39#else
40static char *rcsid = "$NetBSD: rcmd.c,v 1.12 1995/06/03 22:33:34 mycroft Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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,84 @@ 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>
49#include <netgroup.h>
60 50
61int __ivaliduser __P((FILE *, u_long, const char *, const char *)); 51int __ivaliduser(FILE *, in_addr_t, const char *, const char *);
62static int __icheckhost __P((u_long, const char *)); 52int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t,
53 const char *, const char *);
54static int __icheckhost(struct sockaddr *, socklen_t, const char *);
55static char *__gethostloop(struct sockaddr *, socklen_t);
56
57int
58rcmd(char **ahost, int rport, const char *locuser, const char *remuser,
59 const char *cmd, int *fd2p)
60{
61 return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET);
62}
63 63
64int 64int
65rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 65rcmd_af(char **ahost, int porta, const char *locuser, const char *remuser,
66 char **ahost; 66 const char *cmd, int *fd2p, int af)
67 u_short rport;
68 const char *locuser, *remuser, *cmd;
69 int *fd2p;
70{ 67{
71 struct hostent *hp; 68 static char hbuf[MAXHOSTNAMELEN];
72 struct sockaddr_in sin, from; 69 char pbuf[NI_MAXSERV];
73 fd_set reads; 70 struct addrinfo hints, *res, *r;
74 long oldmask; 71 int error;
72 struct sockaddr_storage from;
73 fd_set *readsp = NULL;
74 sigset_t oldmask, mask;
75 pid_t pid; 75 pid_t pid;
76 int s, lport, timo; 76 int s, lport, timo;
77 char c; 77 char c, *p;
78 int refused;
79 in_port_t rport = porta;
80
81 /* call rcmdsh() with specified remote shell if appropriate. */
82 if (!issetugid() && (p = getenv("RSH")) && *p) {
83 struct servent *sp = getservbyname("shell", "tcp");
84
85 if (sp && sp->s_port == rport)
86 return (rcmdsh(ahost, rport, locuser, remuser,
87 cmd, p));
88 }
89
90 /* use rsh(1) if non-root and remote port is shell. */
91 if (geteuid()) {
92 struct servent *sp = getservbyname("shell", "tcp");
93
94 if (sp && sp->s_port == rport)
95 return (rcmdsh(ahost, rport, locuser, remuser,
96 cmd, NULL));
97 }
78 98
79 pid = getpid(); 99 pid = getpid();
80 hp = gethostbyname(*ahost); 100 snprintf(pbuf, sizeof(pbuf), "%u", ntohs(rport));
81 if (hp == NULL) { 101 memset(&hints, 0, sizeof(hints));
82 herror(*ahost); 102 hints.ai_family = af;
103 hints.ai_socktype = SOCK_STREAM;
104 hints.ai_flags = AI_CANONNAME;
105 error = getaddrinfo(*ahost, pbuf, &hints, &res);
106 if (error) {
107#if 0
108 warnx("%s: %s", *ahost, gai_strerror(error));
109#endif
83 return (-1); 110 return (-1);
84 } 111 }
85 *ahost = hp->h_name; 112 if (res->ai_canonname) {
86 oldmask = sigblock(sigmask(SIGURG)); 113 strlcpy(hbuf, res->ai_canonname, sizeof(hbuf));
114 *ahost = hbuf;
115 } else
116 ; /*XXX*/
117
118 r = res;
119 refused = 0;
120 sigemptyset(&mask);
121 sigaddset(&mask, SIGURG);
122 sigprocmask(SIG_BLOCK, &mask, &oldmask);
87 for (timo = 1, lport = IPPORT_RESERVED - 1;;) { 123 for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
88 s = rresvport(&lport); 124 s = rresvport_af(&lport, r->ai_family);
89 if (s < 0) { 125 if (s < 0) {
90 if (errno == EAGAIN) 126 if (errno == EAGAIN)
91 (void)fprintf(stderr, 127 (void)fprintf(stderr,
@@ -93,54 +129,84 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
93 else 129 else
94 (void)fprintf(stderr, "rcmd: socket: %s\n", 130 (void)fprintf(stderr, "rcmd: socket: %s\n",
95 strerror(errno)); 131 strerror(errno));
96 sigsetmask(oldmask); 132 if (r->ai_next) {
97 return (-1); 133 r = r->ai_next;
134 continue;
135 } else {
136 sigprocmask(SIG_SETMASK, &oldmask, NULL);
137 freeaddrinfo(res);
138 return (-1);
139 }
98 } 140 }
99 fcntl(s, F_SETOWN, pid); 141 fcntl(s, F_SETOWN, pid);
100 sin.sin_len = sizeof(struct sockaddr_in); 142 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; 143 break;
106 (void)close(s); 144 (void)close(s);
107 if (errno == EADDRINUSE) { 145 if (errno == EADDRINUSE) {
108 lport--; 146 lport--;
109 continue; 147 continue;
110 } 148 }
111 if (errno == ECONNREFUSED && timo <= 16) { 149 if (errno == ECONNREFUSED)
112 (void)sleep(timo); 150 refused++;
113 timo *= 2; 151 if (r->ai_next) {
114 continue;
115 }
116 if (hp->h_addr_list[1] != NULL) {
117 int oerrno = errno; 152 int oerrno = errno;
118 153 char hbuf[NI_MAXHOST];
119 (void)fprintf(stderr, "connect to address %s: ", 154 const int niflags = NI_NUMERICHOST;
120 inet_ntoa(sin.sin_addr)); 155
156 hbuf[0] = '\0';
157 if (getnameinfo(r->ai_addr, r->ai_addrlen,
158 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
159 strlcpy(hbuf, "(invalid)", sizeof hbuf);
160 (void)fprintf(stderr, "connect to address %s: ", hbuf);
121 errno = oerrno; 161 errno = oerrno;
122 perror(0); 162 perror(0);
123 hp->h_addr_list++; 163 r = r->ai_next;
124 bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); 164 hbuf[0] = '\0';
125 (void)fprintf(stderr, "Trying %s...\n", 165 if (getnameinfo(r->ai_addr, r->ai_addrlen,
126 inet_ntoa(sin.sin_addr)); 166 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
167 strlcpy(hbuf, "(invalid)", sizeof hbuf);
168 (void)fprintf(stderr, "Trying %s...\n", hbuf);
127 continue; 169 continue;
128 } 170 }
129 (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); 171 if (refused && timo <= 16) {
130 sigsetmask(oldmask); 172 (void)sleep(timo);
173 timo *= 2;
174 r = res;
175 refused = 0;
176 continue;
177 }
178 (void)fprintf(stderr, "%s: %s\n", res->ai_canonname,
179 strerror(errno));
180 sigprocmask(SIG_SETMASK, &oldmask, NULL);
181 freeaddrinfo(res);
131 return (-1); 182 return (-1);
132 } 183 }
184 /* given "af" can be PF_UNSPEC, we need the real af for "s" */
185 af = r->ai_family;
186 freeaddrinfo(res);
187#if 0
188 /*
189 * try to rresvport() to the same port. This will make rresvport()
190 * fail it's first bind, resulting in it choosing a random port.
191 */
133 lport--; 192 lport--;
193#endif
134 if (fd2p == 0) { 194 if (fd2p == 0) {
135 write(s, "", 1); 195 write(s, "", 1);
136 lport = 0; 196 lport = 0;
137 } else { 197 } else {
138 char num[8]; 198 char num[8];
139 int s2 = rresvport(&lport), s3; 199 int s2 = rresvport_af(&lport, af), s3;
140 int len = sizeof(from); 200 socklen_t len = sizeof(from);
201 int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask);
141 202
142 if (s2 < 0) 203 if (s2 < 0)
143 goto bad; 204 goto bad;
205 readsp = (fd_set *)malloc(fdssize);
206 if (readsp == NULL) {
207 close(s2);
208 goto bad;
209 }
144 listen(s2, 1); 210 listen(s2, 1);
145 (void)snprintf(num, sizeof(num), "%d", lport); 211 (void)snprintf(num, sizeof(num), "%d", lport);
146 if (write(s, num, strlen(num)+1) != strlen(num)+1) { 212 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
@@ -150,12 +216,13 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
150 (void)close(s2); 216 (void)close(s2);
151 goto bad; 217 goto bad;
152 } 218 }
153 FD_ZERO(&reads); 219again:
154 FD_SET(s, &reads); 220 bzero(readsp, fdssize);
155 FD_SET(s2, &reads); 221 FD_SET(s, readsp);
222 FD_SET(s2, readsp);
156 errno = 0; 223 errno = 0;
157 if (select(MAX(s, s2) + 1, &reads, 0, 0, 0) < 1 || 224 if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 ||
158 !FD_ISSET(s2, &reads)) { 225 !FD_ISSET(s2, readsp)) {
159 if (errno != 0) 226 if (errno != 0)
160 (void)fprintf(stderr, 227 (void)fprintf(stderr,
161 "rcmd: select (setting up stderr): %s\n", 228 "rcmd: select (setting up stderr): %s\n",
@@ -167,21 +234,48 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
167 goto bad; 234 goto bad;
168 } 235 }
169 s3 = accept(s2, (struct sockaddr *)&from, &len); 236 s3 = accept(s2, (struct sockaddr *)&from, &len);
170 (void)close(s2);
171 if (s3 < 0) { 237 if (s3 < 0) {
172 (void)fprintf(stderr, 238 (void)fprintf(stderr,
173 "rcmd: accept: %s\n", strerror(errno)); 239 "rcmd: accept: %s\n", strerror(errno));
174 lport = 0; 240 lport = 0;
241 close(s2);
175 goto bad; 242 goto bad;
176 } 243 }
244
245 /*
246 * XXX careful for ftp bounce attacks. If discovered, shut them
247 * down and check for the real auxiliary channel to connect.
248 */
249 switch (from.ss_family) {
250 case AF_INET:
251 case AF_INET6:
252 if (getnameinfo((struct sockaddr *)&from, len,
253 NULL, 0, num, sizeof(num), NI_NUMERICSERV) == 0 &&
254 atoi(num) != 20) {
255 break;
256 }
257 close(s3);
258 goto again;
259 default:
260 break;
261 }
262 (void)close(s2);
263
177 *fd2p = s3; 264 *fd2p = s3;
178 from.sin_port = ntohs(from.sin_port); 265 switch (from.ss_family) {
179 if (from.sin_family != AF_INET || 266 case AF_INET:
180 from.sin_port >= IPPORT_RESERVED || 267 case AF_INET6:
181 from.sin_port < IPPORT_RESERVED / 2) { 268 if (getnameinfo((struct sockaddr *)&from, len,
182 (void)fprintf(stderr, 269 NULL, 0, num, sizeof(num), NI_NUMERICSERV) != 0 ||
183 "socket: protocol failure in circuit setup.\n"); 270 (atoi(num) >= IPPORT_RESERVED ||
184 goto bad2; 271 atoi(num) < IPPORT_RESERVED / 2)) {
272 (void)fprintf(stderr,
273 "socket: protocol failure in circuit setup.\n");
274 goto bad2;
275 }
276 break;
277 default:
278 break;
185 } 279 }
186 } 280 }
187 (void)write(s, locuser, strlen(locuser)+1); 281 (void)write(s, locuser, strlen(locuser)+1);
@@ -200,70 +294,44 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
200 } 294 }
201 goto bad2; 295 goto bad2;
202 } 296 }
203 sigsetmask(oldmask); 297 sigprocmask(SIG_SETMASK, &oldmask, NULL);
298 free(readsp);
204 return (s); 299 return (s);
205bad2: 300bad2:
206 if (lport) 301 if (lport)
207 (void)close(*fd2p); 302 (void)close(*fd2p);
208bad: 303bad:
304 if (readsp)
305 free(readsp);
209 (void)close(s); 306 (void)close(s);
210 sigsetmask(oldmask); 307 sigprocmask(SIG_SETMASK, &oldmask, NULL);
211 return (-1); 308 return (-1);
212} 309}
213 310
214int
215rresvport(alport)
216 int *alport;
217{
218 struct sockaddr_in sin;
219 int s;
220
221 sin.sin_len = sizeof(struct sockaddr_in);
222 sin.sin_family = AF_INET;
223 sin.sin_addr.s_addr = INADDR_ANY;
224 s = socket(AF_INET, SOCK_STREAM, 0);
225 if (s < 0)
226 return (-1);
227 for (;;) {
228 sin.sin_port = htons((u_short)*alport);
229 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
230 return (s);
231 if (errno != EADDRINUSE) {
232 (void)close(s);
233 return (-1);
234 }
235 (*alport)--;
236 if (*alport == IPPORT_RESERVED/2) {
237 (void)close(s);
238 errno = EAGAIN; /* close */
239 return (-1);
240 }
241 }
242}
243
244int __check_rhosts_file = 1; 311int __check_rhosts_file = 1;
245char *__rcmd_errstr; 312char *__rcmd_errstr;
246 313
247int 314int
248ruserok(rhost, superuser, ruser, luser) 315ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
249 const char *rhost, *ruser, *luser;
250 int superuser;
251{ 316{
252 struct hostent *hp; 317 struct addrinfo hints, *res, *r;
253 char **ap; 318 int error;
254 int i; 319
255#define MAXADDRS 35 320 memset(&hints, 0, sizeof(hints));
256 u_long addrs[MAXADDRS + 1]; 321 hints.ai_family = PF_UNSPEC;
257 322 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
258 if ((hp = gethostbyname(rhost)) == NULL) 323 error = getaddrinfo(rhost, "0", &hints, &res);
324 if (error)
259 return (-1); 325 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 326
264 for (i = 0; i < MAXADDRS && addrs[i]; i++) 327 for (r = res; r; r = r->ai_next) {
265 if (iruserok(addrs[i], superuser, ruser, luser) == 0) 328 if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser,
329 luser) == 0) {
330 freeaddrinfo(res);
266 return (0); 331 return (0);
332 }
333 }
334 freeaddrinfo(res);
267 return (-1); 335 return (-1);
268} 336}
269 337
@@ -277,12 +345,24 @@ ruserok(rhost, superuser, ruser, luser)
277 * Returns 0 if ok, -1 if not ok. 345 * Returns 0 if ok, -1 if not ok.
278 */ 346 */
279int 347int
280iruserok(raddr, superuser, ruser, luser) 348iruserok(u_int32_t raddr, int superuser, const char *ruser, const char *luser)
281 u_long raddr;
282 int superuser;
283 const char *ruser, *luser;
284{ 349{
285 register char *cp; 350 struct sockaddr_in sin;
351
352 memset(&sin, 0, sizeof(sin));
353 sin.sin_family = AF_INET;
354 sin.sin_len = sizeof(struct sockaddr_in);
355 memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr));
356 return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser,
357 luser);
358}
359
360int
361iruserok_sa(const void *raddr, int rlen, int superuser, const char *ruser,
362 const char *luser)
363{
364 struct sockaddr *sa;
365 char *cp;
286 struct stat sbuf; 366 struct stat sbuf;
287 struct passwd *pwd; 367 struct passwd *pwd;
288 FILE *hostf; 368 FILE *hostf;
@@ -290,22 +370,26 @@ iruserok(raddr, superuser, ruser, luser)
290 int first; 370 int first;
291 char pbuf[MAXPATHLEN]; 371 char pbuf[MAXPATHLEN];
292 372
373 sa = (struct sockaddr *)raddr;
293 first = 1; 374 first = 1;
294 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); 375 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
295again: 376again:
296 if (hostf) { 377 if (hostf) {
297 if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { 378 if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) {
298 (void)fclose(hostf); 379 (void)fclose(hostf);
299 return (0); 380 return (0);
300 } 381 }
301 (void)fclose(hostf); 382 (void)fclose(hostf);
302 } 383 }
303 if (first == 1 && (__check_rhosts_file || superuser)) { 384 if (first == 1 && (__check_rhosts_file || superuser)) {
385 int len;
386
304 first = 0; 387 first = 0;
305 if ((pwd = getpwnam(luser)) == NULL) 388 if ((pwd = getpwnam(luser)) == NULL)
306 return (-1); 389 return (-1);
307 (void)strcpy(pbuf, pwd->pw_dir); 390 len = snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir);
308 (void)strcat(pbuf, "/.rhosts"); 391 if (len < 0 || len >= sizeof pbuf)
392 return (-1);
309 393
310 /* 394 /*
311 * Change effective uid while opening .rhosts. If root and 395 * Change effective uid while opening .rhosts. If root and
@@ -333,7 +417,7 @@ again:
333 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) 417 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
334 cp = "bad .rhosts owner"; 418 cp = "bad .rhosts owner";
335 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) 419 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
336 cp = ".rhosts writeable by other than owner"; 420 cp = ".rhosts writable by other than owner";
337 /* If there were any problems, quit. */ 421 /* If there were any problems, quit. */
338 if (cp) { 422 if (cp) {
339 __rcmd_errstr = cp; 423 __rcmd_errstr = cp;
@@ -352,41 +436,58 @@ again:
352 * Returns 0 if ok, -1 if not ok. 436 * Returns 0 if ok, -1 if not ok.
353 */ 437 */
354int 438int
355__ivaliduser(hostf, raddr, luser, ruser) 439__ivaliduser(FILE *hostf, in_addr_t raddrl, const char *luser,
356 FILE *hostf; 440 const char *ruser)
357 u_long raddr; 441{
358 const char *luser, *ruser; 442 struct sockaddr_in sin;
443
444 memset(&sin, 0, sizeof(sin));
445 sin.sin_family = AF_INET;
446 sin.sin_len = sizeof(struct sockaddr_in);
447 memcpy(&sin.sin_addr, &raddrl, sizeof(sin.sin_addr));
448 return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len,
449 luser, ruser);
450}
451
452int
453__ivaliduser_sa(FILE *hostf, struct sockaddr *raddr, socklen_t salen,
454 const char *luser, const char *ruser)
359{ 455{
360 register char *user, *p; 456 char *user, *p;
361 int ch; 457 char *buf;
362 char buf[MAXHOSTNAMELEN + 128]; /* host + login */
363 const char *auser, *ahost; 458 const char *auser, *ahost;
364 int hostok, userok; 459 int hostok, userok;
365 char rhost[MAXHOSTNAMELEN]; 460 char *rhost = (char *)-1;
366 struct hostent *hp;
367 char domain[MAXHOSTNAMELEN]; 461 char domain[MAXHOSTNAMELEN];
462 size_t buflen;
368 463
369 getdomainname(domain, sizeof(domain)); 464 getdomainname(domain, sizeof(domain));
370 465
371 while (fgets(buf, sizeof(buf), hostf)) { 466 while ((buf = fgetln(hostf, &buflen))) {
372 p = buf; 467 p = buf;
373 /* Skip lines that are too long. */ 468 if (*p == '#')
374 if (strchr(p, '\n') == NULL) {
375 while ((ch = getc(hostf)) != '\n' && ch != EOF);
376 continue; 469 continue;
377 } 470 while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') {
378 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { 471 if (!isprint(*p))
472 goto bail;
379 *p = isupper(*p) ? tolower(*p) : *p; 473 *p = isupper(*p) ? tolower(*p) : *p;
380 p++; 474 p++;
381 } 475 }
476 if (p >= buf + buflen)
477 continue;
382 if (*p == ' ' || *p == '\t') { 478 if (*p == ' ' || *p == '\t') {
383 *p++ = '\0'; 479 *p++ = '\0';
384 while (*p == ' ' || *p == '\t') 480 while (p < buf + buflen && (*p == ' ' || *p == '\t'))
385 p++; 481 p++;
482 if (p >= buf + buflen)
483 continue;
386 user = p; 484 user = p;
387 while (*p != '\n' && *p != ' ' && 485 while (p < buf + buflen && *p != '\n' && *p != ' ' &&
388 *p != '\t' && *p != '\0') 486 *p != '\t') {
487 if (!isprint(*p))
488 goto bail;
389 p++; 489 p++;
490 }
390 } else 491 } else
391 user = p; 492 user = p;
392 *p = '\0'; 493 *p = '\0';
@@ -397,27 +498,29 @@ __ivaliduser(hostf, raddr, luser, ruser)
397 auser = *user ? user : luser; 498 auser = *user ? user : luser;
398 ahost = buf; 499 ahost = buf;
399 500
400 if ((hp = gethostbyaddr((char *) &raddr, 501 if (strlen(ahost) >= MAXHOSTNAMELEN)
401 sizeof(raddr), AF_INET)) == NULL) { 502 continue;
402 abort();
403 return -1;
404 }
405 (void) strncpy(rhost, hp->h_name, sizeof(rhost));
406 rhost[sizeof(rhost) - 1] = '\0';
407 503
504 /*
505 * innetgr() must lookup a hostname (we do not attempt
506 * to change the semantics so that netgroups may have
507 * #.#.#.# addresses in the list.)
508 */
408 if (ahost[0] == '+') 509 if (ahost[0] == '+')
409 switch (ahost[1]) { 510 switch (ahost[1]) {
410 case '\0': 511 case '\0':
411 hostok = 1; 512 hostok = 1;
412 break; 513 break;
413
414 case '@': 514 case '@':
415 hostok = innetgr(&ahost[2], rhost, NULL, 515 if (rhost == (char *)-1)
416 domain); 516 rhost = __gethostloop(raddr, salen);
517 hostok = 0;
518 if (rhost)
519 hostok = innetgr(&ahost[2], rhost,
520 NULL, domain);
417 break; 521 break;
418
419 default: 522 default:
420 hostok = __icheckhost(raddr, &ahost[1]); 523 hostok = __icheckhost(raddr, salen, &ahost[1]);
421 break; 524 break;
422 } 525 }
423 else if (ahost[0] == '-') 526 else if (ahost[0] == '-')
@@ -425,18 +528,20 @@ __ivaliduser(hostf, raddr, luser, ruser)
425 case '\0': 528 case '\0':
426 hostok = -1; 529 hostok = -1;
427 break; 530 break;
428
429 case '@': 531 case '@':
430 hostok = -innetgr(&ahost[2], rhost, NULL, 532 if (rhost == (char *)-1)
431 domain); 533 rhost = __gethostloop(raddr, salen);
534 hostok = 0;
535 if (rhost)
536 hostok = -innetgr(&ahost[2], rhost,
537 NULL, domain);
432 break; 538 break;
433
434 default: 539 default:
435 hostok = -__icheckhost(raddr, &ahost[1]); 540 hostok = -__icheckhost(raddr, salen, &ahost[1]);
436 break; 541 break;
437 } 542 }
438 else 543 else
439 hostok = __icheckhost(raddr, ahost); 544 hostok = __icheckhost(raddr, salen, ahost);
440 545
441 546
442 if (auser[0] == '+') 547 if (auser[0] == '+')
@@ -444,14 +549,12 @@ __ivaliduser(hostf, raddr, luser, ruser)
444 case '\0': 549 case '\0':
445 userok = 1; 550 userok = 1;
446 break; 551 break;
447
448 case '@': 552 case '@':
449 userok = innetgr(&auser[2], NULL, ruser, 553 userok = innetgr(&auser[2], NULL, ruser,
450 domain); 554 domain);
451 break; 555 break;
452
453 default: 556 default:
454 userok = strcmp(ruser, &auser[1]) == 0; 557 userok = strcmp(ruser, &auser[1]) ? 0 : 1;
455 break; 558 break;
456 } 559 }
457 else if (auser[0] == '-') 560 else if (auser[0] == '-')
@@ -459,59 +562,130 @@ __ivaliduser(hostf, raddr, luser, ruser)
459 case '\0': 562 case '\0':
460 userok = -1; 563 userok = -1;
461 break; 564 break;
462
463 case '@': 565 case '@':
464 userok = -innetgr(&auser[2], NULL, ruser, 566 userok = -innetgr(&auser[2], NULL, ruser,
465 domain); 567 domain);
466 break; 568 break;
467
468 default: 569 default:
469 userok = -(strcmp(ruser, &auser[1]) == 0); 570 userok = strcmp(ruser, &auser[1]) ? 0 : -1;
470 break; 571 break;
471 } 572 }
472 else 573 else
473 userok = strcmp(ruser, auser) == 0; 574 userok = strcmp(ruser, auser) ? 0 : 1;
474 575
475 /* Check if one component did not match */ 576 /* Check if one component did not match */
476 if (hostok == 0 || userok == 0) 577 if (hostok == 0 || userok == 0)
477 continue; 578 continue;
478 579
479 /* Check if we got a forbidden pair */ 580 /* Check if we got a forbidden pair */
480 if (userok == -1 || hostok == -1) 581 if (userok <= -1 || hostok <= -1)
481 return -1; 582 return (-1);
482 583
483 /* Check if we got a valid pair */ 584 /* Check if we got a valid pair */
484 if (hostok == 1 && userok == 1) 585 if (hostok >= 1 && userok >= 1)
485 return 0; 586 return (0);
486 } 587 }
487 return -1; 588bail:
589 return (-1);
488} 590}
489 591
490/* 592/*
491 * Returns "true" if match, 0 if no match. 593 * Returns "true" if match, 0 if no match. If we do not find any
594 * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
492 */ 595 */
493static int 596static int
494__icheckhost(raddr, lhost) 597__icheckhost(struct sockaddr *raddr, socklen_t salen, const char *lhost)
495 u_long raddr;
496 const char *lhost;
497{ 598{
498 register struct hostent *hp; 599 struct addrinfo hints, *res, *r;
499 register u_long laddr; 600 char h1[NI_MAXHOST], h2[NI_MAXHOST];
500 register char **pp; 601 int error;
501 602 const int niflags = NI_NUMERICHOST;
502 /* Try for raw ip address first. */ 603
503 if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) 604 h1[0] = '\0';
504 return (raddr == laddr); 605 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
606 niflags) != 0)
607 return (0);
505 608
506 /* Better be a hostname. */ 609 /* Resolve laddr into sockaddr */
507 if ((hp = gethostbyname(lhost)) == NULL) 610 memset(&hints, 0, sizeof(hints));
611 hints.ai_family = raddr->sa_family;
612 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
613 res = NULL;
614 error = getaddrinfo(lhost, "0", &hints, &res);
615 if (error)
508 return (0); 616 return (0);
509 617
510 /* Spin through ip addresses. */ 618 /*
511 for (pp = hp->h_addr_list; *pp; ++pp) 619 * Try string comparisons between raddr and laddr.
512 if (!bcmp(&raddr, *pp, sizeof(u_long))) 620 */
621 for (r = res; r; r = r->ai_next) {
622 h2[0] = '\0';
623 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
624 NULL, 0, niflags) != 0)
625 continue;
626 if (strcmp(h1, h2) == 0) {
627 freeaddrinfo(res);
513 return (1); 628 return (1);
629 }
630 }
514 631
515 /* No match. */ 632 /* No match. */
633 freeaddrinfo(res);
516 return (0); 634 return (0);
517} 635}
636
637/*
638 * Return the hostname associated with the supplied address.
639 * Do a reverse lookup as well for security. If a loop cannot
640 * be found, pack the result of inet_ntoa() into the string.
641 */
642static char *
643__gethostloop(struct sockaddr *raddr, socklen_t salen)
644{
645 static char remotehost[NI_MAXHOST];
646 char h1[NI_MAXHOST], h2[NI_MAXHOST];
647 struct addrinfo hints, *res, *r;
648 int error;
649 const int niflags = NI_NUMERICHOST;
650
651 h1[0] = remotehost[0] = '\0';
652 if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost),
653 NULL, 0, NI_NAMEREQD) != 0)
654 return (NULL);
655 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
656 niflags) != 0)
657 return (NULL);
658
659 /*
660 * Look up the name and check that the supplied
661 * address is in the list
662 */
663 memset(&hints, 0, sizeof(hints));
664 hints.ai_family = raddr->sa_family;
665 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
666 hints.ai_flags = AI_CANONNAME;
667 res = NULL;
668 error = getaddrinfo(remotehost, "0", &hints, &res);
669 if (error)
670 return (NULL);
671
672 for (r = res; r; r = r->ai_next) {
673 h2[0] = '\0';
674 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
675 NULL, 0, niflags) != 0)
676 continue;
677 if (strcmp(h1, h2) == 0) {
678 freeaddrinfo(res);
679 return (remotehost);
680 }
681 }
682
683 /*
684 * either the DNS adminstrator has made a configuration
685 * mistake, or someone has attempted to spoof us
686 */
687 syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s",
688 h1, res->ai_canonname ? res->ai_canonname : remotehost);
689 freeaddrinfo(res);
690 return (NULL);
691}
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3
new file mode 100644
index 0000000000..07a28beeba
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.3
@@ -0,0 +1,96 @@
1.\" $OpenBSD: rcmdsh.3,v 1.12 2007/05/31 19:19:30 jmc 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: May 31 2007 $
31.Dt RCMDSH 3
32.Os
33.Sh NAME
34.Nm rcmdsh
35.Nd return a stream to a remote command without superuser
36.Sh SYNOPSIS
37.Fd #include <unistd.h>
38.Ft int
39.Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog"
40.Sh DESCRIPTION
41The
42.Fn rcmdsh
43function is used by normal users to execute a command on a remote machine
44using an authentication scheme based on reserved port numbers using
45.Xr rsh 1
46or the value of
47.Fa rshprog
48(if non-null).
49.Fa rshprog
50may be a fully-qualified path, a non-qualified command, or a command containing
51space-separated command line arguments.
52.Pp
53The
54.Fn rcmdsh
55function looks up the host
56.Fa *ahost
57using
58.Xr gethostbyname 3 ,
59returning \-1 if the host does not exist.
60Otherwise
61.Fa *ahost
62is set to the standard name of the host and a connection is established to
63a server residing at the well-known Internet port
64.Li shell/tcp
65(or whatever port is used by
66.Fa rshprog ) .
67The parameter
68.Fa inport
69is ignored; it is only included to provide an interface similar to
70.Xr rcmd 3 .
71.Pp
72If the connection succeeds, a socket in the
73.Tn UNIX
74domain of type
75.Dv SOCK_STREAM
76is returned to the caller, and given to the remote
77command as stdin and stdout, and stderr.
78.Sh DIAGNOSTICS
79The
80.Fn rcmdsh
81function returns a valid socket descriptor on success.
82It returns \-1 on error and prints a diagnostic message on the standard error.
83.Sh SEE ALSO
84.Xr rsh 1 ,
85.Xr socketpair 2 ,
86.Xr rcmd 3 ,
87.Xr rshd 8
88.Sh HISTORY
89The
90.Fn rcmdsh
91function first appeared in
92.Ox 2.0 .
93.Sh BUGS
94If
95.Xr rsh 1
96encounters an error, a file descriptor is still returned instead of \-1.
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c
new file mode 100644
index 0000000000..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 */
55int
56rcmdsh(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
38static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94";
39#else
40static char rcsid[] = "$NetBSD: recv.c,v 1.6 1995/02/25 06:20:54 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
49ssize_t 36ssize_t
50recv(s, buf, len, flags) 37recv(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
58static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_comp.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static 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
71static int dn_find(); 66static 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 */
80dn_expand(msg, eomorig, comp_dn, exp_dn, length) 75int
81 const u_char *msg, *eomorig, *comp_dn; 76dn_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 */
160dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) 157int
161 const u_char *exp_dn; 158dn_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) 235int
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
263static int
264mklower(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 */
272static int 277static int
273dn_find(exp_dn, msg, dnptrs, lastdnptr) 278dn_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
346int
347res_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 */
375int
376res_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
326u_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 */
391int
392res_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 */
420int
421res_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
435u_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 */
448u_int16_t
449res_getshort(msgp)
450 const u_char *msgp;
451{
452 return (_getshort(msgp));
453}
454#endif
455
336u_int32_t 456u_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
346void 465void
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
358void 471void
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
69const 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
88const 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
index d841293f18..246fefef3c 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */ 1/* $OpenBSD: res_debug.c,v 1.22 2007/10/11 18:36:41 jakob Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
4 * Copyright (c) 1985, 1990, 1993 6 * Copyright (c) 1985, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,11 +14,7 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
@@ -50,174 +48,179 @@
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 * SOFTWARE. 49 * SOFTWARE.
52 * - 50 * -
51 * Portions Copyright (c) 1995 by International Business Machines, Inc.
52 *
53 * International Business Machines, Inc. (hereinafter called IBM) grants
54 * permission under its copyrights to use, copy, modify, and distribute this
55 * Software with or without fee, provided that the above copyright notice and
56 * all paragraphs of this notice appear in all copies, and that the name of IBM
57 * not be used in connection with the marketing of any product incorporating
58 * the Software or modifications thereof, without specific, written prior
59 * permission.
60 *
61 * To the extent it has a right to do so, IBM grants an immunity from suit
62 * under its patents, if any, for the use, sale or manufacture of products to
63 * the extent that such products are used for performing Domain Name System
64 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
65 * granted for any product per se or for any other function of any product.
66 *
67 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
68 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
69 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
70 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
71 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
72 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
53 * --Copyright-- 73 * --Copyright--
54 */ 74 */
55 75
56#if defined(LIBC_SCCS) && !defined(lint)
57#if 0
58static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
59#else
60static 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> 76#include <sys/param.h>
77#include <sys/types.h>
78#include <sys/socket.h>
65#include <netinet/in.h> 79#include <netinet/in.h>
66#include <arpa/inet.h> 80#include <arpa/inet.h>
67#include <arpa/nameser.h> 81#include <arpa/nameser.h>
82
83#include <ctype.h>
84#include <netdb.h>
68#include <resolv.h> 85#include <resolv.h>
69#include <stdio.h> 86#include <stdio.h>
87#include <time.h>
88
89#include <stdlib.h>
70#include <string.h> 90#include <string.h>
71 91
72void __fp_query(); 92#include "thread_private.h"
73char *__p_class(), *__p_time(), *__p_type(); 93
74char *p_cdname(), *p_fqname(), *p_rr(); 94extern const char *_res_opcodes[];
75static char *p_option __P((u_int32_t)); 95extern const char *_res_resultcodes[];
76 96
77char *_res_opcodes[] = { 97static const char *loc_ntoal(const u_char *binary, char *ascii, int ascii_len);
78 "QUERY", 98
79 "IQUERY", 99/* XXX: we should use getservbyport() instead. */
80 "CQUERYM", 100static const char *
81 "CQUERYU", 101dewks(int wks)
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
96char *_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
115static char retbuf[16];
116
117static char *
118dewks(wks)
119 int wks;
120{ 102{
103 static char nbuf[20];
104
121 switch (wks) { 105 switch (wks) {
122 case 5: return("rje"); 106 case 5: return "rje";
123 case 7: return("echo"); 107 case 7: return "echo";
124 case 9: return("discard"); 108 case 9: return "discard";
125 case 11: return("systat"); 109 case 11: return "systat";
126 case 13: return("daytime"); 110 case 13: return "daytime";
127 case 15: return("netstat"); 111 case 15: return "netstat";
128 case 17: return("qotd"); 112 case 17: return "qotd";
129 case 19: return("chargen"); 113 case 19: return "chargen";
130 case 20: return("ftp-data"); 114 case 20: return "ftp-data";
131 case 21: return("ftp"); 115 case 21: return "ftp";
132 case 23: return("telnet"); 116 case 23: return "telnet";
133 case 25: return("smtp"); 117 case 25: return "smtp";
134 case 37: return("time"); 118 case 37: return "time";
135 case 39: return("rlp"); 119 case 39: return "rlp";
136 case 42: return("name"); 120 case 42: return "name";
137 case 43: return("whois"); 121 case 43: return "whois";
138 case 53: return("domain"); 122 case 53: return "domain";
139 case 57: return("apts"); 123 case 57: return "apts";
140 case 59: return("apfs"); 124 case 59: return "apfs";
141 case 67: return("bootps"); 125 case 67: return "bootps";
142 case 68: return("bootpc"); 126 case 68: return "bootpc";
143 case 69: return("tftp"); 127 case 69: return "tftp";
144 case 77: return("rje"); 128 case 77: return "rje";
145 case 79: return("finger"); 129 case 79: return "finger";
146 case 87: return("link"); 130 case 87: return "link";
147 case 95: return("supdup"); 131 case 95: return "supdup";
148 case 100: return("newacct"); 132 case 100: return "newacct";
149 case 101: return("hostnames"); 133 case 101: return "hostnames";
150 case 102: return("iso-tsap"); 134 case 102: return "iso-tsap";
151 case 103: return("x400"); 135 case 103: return "x400";
152 case 104: return("x400-snd"); 136 case 104: return "x400-snd";
153 case 105: return("csnet-ns"); 137 case 105: return "csnet-ns";
154 case 109: return("pop-2"); 138 case 109: return "pop-2";
155 case 111: return("sunrpc"); 139 case 111: return "sunrpc";
156 case 113: return("auth"); 140 case 113: return "auth";
157 case 115: return("sftp"); 141 case 115: return "sftp";
158 case 117: return("uucp-path"); 142 case 117: return "uucp-path";
159 case 119: return("nntp"); 143 case 119: return "nntp";
160 case 121: return("erpc"); 144 case 121: return "erpc";
161 case 123: return("ntp"); 145 case 123: return "ntp";
162 case 133: return("statsrv"); 146 case 133: return "statsrv";
163 case 136: return("profile"); 147 case 136: return "profile";
164 case 144: return("NeWS"); 148 case 144: return "NeWS";
165 case 161: return("snmp"); 149 case 161: return "snmp";
166 case 162: return("snmp-trap"); 150 case 162: return "snmp-trap";
167 case 170: return("print-srv"); 151 case 170: return "print-srv";
168 default: (void) sprintf(retbuf, "%d", wks); return(retbuf); 152 default:
153 (void) snprintf(nbuf, sizeof nbuf, "%d", wks);
154 return (nbuf);
169 } 155 }
170} 156}
171 157
172static char * 158/* XXX: we should use getprotobynumber() instead. */
173deproto(protonum) 159static const char *
174 int protonum; 160deproto(int protonum)
175{ 161{
162 static char nbuf[20];
163
176 switch (protonum) { 164 switch (protonum) {
177 case 1: return("icmp"); 165 case 1: return "icmp";
178 case 2: return("igmp"); 166 case 2: return "igmp";
179 case 3: return("ggp"); 167 case 3: return "ggp";
180 case 5: return("st"); 168 case 5: return "st";
181 case 6: return("tcp"); 169 case 6: return "tcp";
182 case 7: return("ucl"); 170 case 7: return "ucl";
183 case 8: return("egp"); 171 case 8: return "egp";
184 case 9: return("igp"); 172 case 9: return "igp";
185 case 11: return("nvp-II"); 173 case 11: return "nvp-II";
186 case 12: return("pup"); 174 case 12: return "pup";
187 case 16: return("chaos"); 175 case 16: return "chaos";
188 case 17: return("udp"); 176 case 17: return "udp";
189 default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); 177 default:
178 (void) snprintf(nbuf, sizeof nbuf, "%d", protonum);
179 return (nbuf);
190 } 180 }
191} 181}
192 182
193static char * 183static const u_char *
194do_rrset(msg, cp, cnt, pflag, file, hs) 184do_rrset(const u_char *msg, int len, const u_char *cp, int cnt, int pflag,
195 int cnt, pflag; 185 FILE *file, const char *hs)
196 char *cp,*msg, *hs;
197 FILE *file;
198{ 186{
187 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
199 int n; 188 int n;
200 int sflag; 189 int sflag;
190
201 /* 191 /*
202 * Print answer records 192 * Print answer records.
203 */ 193 */
204 sflag = (_res.pfcode & pflag); 194 sflag = (_resp->pfcode & pflag);
205 if (n = ntohs(cnt)) { 195 if ((n = ntohs(cnt))) {
206 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 196 if ((!_resp->pfcode) ||
207 fprintf(file, hs); 197 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
198 fprintf(file, "%s", hs);
208 while (--n >= 0) { 199 while (--n >= 0) {
209 cp = p_rr(cp, msg, file); 200 if ((!_resp->pfcode) || sflag) {
210 if ((cp-msg) > PACKETSZ) 201 cp = p_rr(cp, msg, file);
202 } else {
203 unsigned int dlen;
204 cp += __dn_skipname(cp, cp + MAXCDNAME);
205 cp += INT16SZ;
206 cp += INT16SZ;
207 cp += INT32SZ;
208 dlen = _getshort((u_char*)cp);
209 cp += INT16SZ;
210 cp += dlen;
211 }
212 if ((cp - msg) > len)
211 return (NULL); 213 return (NULL);
212 } 214 }
213 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 215 if ((!_resp->pfcode) ||
216 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
214 putc('\n', file); 217 putc('\n', file);
215 } 218 }
216 return(cp); 219 return (cp);
217} 220}
218 221
219__p_query(msg) 222void
220 char *msg; 223__p_query(const u_char *msg)
221{ 224{
222 __fp_query(msg, stdout); 225 __fp_query(msg, stdout);
223} 226}
@@ -227,19 +230,16 @@ __p_query(msg)
227 * This is intended to be primarily a debugging routine. 230 * This is intended to be primarily a debugging routine.
228 */ 231 */
229void 232void
230__fp_resstat(statp, file) 233__fp_resstat(struct __res_state *statp, FILE *file)
231 struct __res_state *statp;
232 FILE *file;
233{ 234{
234 int bit; 235 u_long mask;
235 236
236 fprintf(file, ";; res options:"); 237 fprintf(file, ";; res options:");
237 if (!statp) 238 if (!statp)
238 statp = &_res; 239 statp = &_res;
239 for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ 240 for (mask = 1; mask != 0; mask <<= 1)
240 if (statp->options & (1<<bit)) 241 if (statp->options & mask)
241 fprintf(file, " %s", p_option(1<<bit)); 242 fprintf(file, " %s", p_option(mask));
242 }
243 putc('\n', file); 243 putc('\n', file);
244} 244}
245 245
@@ -248,109 +248,144 @@ __fp_resstat(statp, file)
248 * This is intended to be primarily a debugging routine. 248 * This is intended to be primarily a debugging routine.
249 */ 249 */
250void 250void
251__fp_query(msg,file) 251__fp_nquery(const u_char *msg, int len, FILE *file)
252 char *msg;
253 FILE *file;
254{ 252{
255 register char *cp; 253 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
256 register HEADER *hp; 254 const u_char *cp, *endMark;
257 register int n; 255 const HEADER *hp;
256 int n;
257
258 if (_res_init(0) == -1)
259 return;
260
261#define TruncTest(x) if (x > endMark) goto trunc
262#define ErrorTest(x) if (x == NULL) goto error
258 263
259 /* 264 /*
260 * Print header fields. 265 * Print header fields.
261 */ 266 */
262 hp = (HEADER *)msg; 267 hp = (HEADER *)msg;
263 cp = msg + sizeof(HEADER); 268 cp = msg + HFIXEDSZ;
264 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 269 endMark = msg + len;
265 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 270 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX) || hp->rcode) {
271 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
266 _res_opcodes[hp->opcode], 272 _res_opcodes[hp->opcode],
267 _res_resultcodes[hp->rcode], 273 _res_resultcodes[hp->rcode],
268 ntohs(hp->id)); 274 ntohs(hp->id));
269 putc('\n', file); 275 putc('\n', file);
270 } 276 }
271 putc(';', file); 277 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX))
272 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 278 putc(';', file);
273 fprintf(file,"; flags:"); 279 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD2)) {
280 fprintf(file, "; flags:");
274 if (hp->qr) 281 if (hp->qr)
275 fprintf(file," qr"); 282 fprintf(file, " qr");
276 if (hp->aa) 283 if (hp->aa)
277 fprintf(file," aa"); 284 fprintf(file, " aa");
278 if (hp->tc) 285 if (hp->tc)
279 fprintf(file," tc"); 286 fprintf(file, " tc");
280 if (hp->rd) 287 if (hp->rd)
281 fprintf(file," rd"); 288 fprintf(file, " rd");
282 if (hp->ra) 289 if (hp->ra)
283 fprintf(file," ra"); 290 fprintf(file, " ra");
284 if (hp->pr) 291 if (hp->unused)
285 fprintf(file," pr"); 292 fprintf(file, " UNUSED-BIT-ON");
293 if (hp->ad)
294 fprintf(file, " ad");
295 if (hp->cd)
296 fprintf(file, " cd");
286 } 297 }
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 298 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD1)) {
288 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 299 fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
289 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 300 fprintf(file, ", Ans: %u", ntohs(hp->ancount));
290 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 301 fprintf(file, ", Auth: %u", ntohs(hp->nscount));
291 fprintf(file,", Addit: %d\n", ntohs(hp->arcount)); 302 fprintf(file, ", Addit: %u", ntohs(hp->arcount));
292 } 303 }
293#if 0 304 if ((!_resp->pfcode) || (_resp->pfcode &
294 if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) { 305 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
295 putc('\n',file); 306 putc('\n',file);
296 } 307 }
297#endif
298 /* 308 /*
299 * Print question records. 309 * Print question records.
300 */ 310 */
301 if (n = ntohs(hp->qdcount)) { 311 if ((n = ntohs(hp->qdcount))) {
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 312 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
303 fprintf(file,";; QUESTIONS:\n"); 313 fprintf(file, ";; QUESTIONS:\n");
304 while (--n >= 0) { 314 while (--n >= 0) {
305 fprintf(file,";;\t"); 315 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
306 cp = p_cdname(cp, msg, file); 316 fprintf(file, ";;\t");
307 if (cp == NULL) 317 TruncTest(cp);
308 return; 318 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
309 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 319 cp = p_cdnname(cp, msg, len, file);
320 else {
321 int n;
322 char name[MAXDNAME];
323
324 if ((n = dn_expand(msg, msg+len, cp, name,
325 sizeof name)) < 0)
326 cp = NULL;
327 else
328 cp += n;
329 }
330 ErrorTest(cp);
331 TruncTest(cp);
332 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
310 fprintf(file, ", type = %s", 333 fprintf(file, ", type = %s",
311 __p_type(_getshort(cp))); 334 __p_type(_getshort((u_char*)cp)));
312 cp += sizeof(u_int16_t); 335 cp += INT16SZ;
313 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 336 TruncTest(cp);
314 fprintf(file, ", class = %s\n\n", 337 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
315 __p_class(_getshort(cp))); 338 fprintf(file, ", class = %s\n",
316 cp += sizeof(u_int16_t); 339 __p_class(_getshort((u_char*)cp)));
340 cp += INT16SZ;
341 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
342 putc('\n', file);
317 } 343 }
318 } 344 }
319 /* 345 /*
320 * Print authoritative answer records 346 * Print authoritative answer records
321 */ 347 */
322 cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, 348 TruncTest(cp);
349 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
323 ";; ANSWERS:\n"); 350 ";; ANSWERS:\n");
324 if (cp == NULL) 351 ErrorTest(cp);
325 return;
326 352
327 /* 353 /*
328 * print name server records 354 * print name server records
329 */ 355 */
330 cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, 356 TruncTest(cp);
357 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
331 ";; AUTHORITY RECORDS:\n"); 358 ";; AUTHORITY RECORDS:\n");
332 if (!cp) 359 ErrorTest(cp);
333 return;
334 360
361 TruncTest(cp);
335 /* 362 /*
336 * print additional records 363 * print additional records
337 */ 364 */
338 cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, 365 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
339 ";; ADDITIONAL RECORDS:\n"); 366 ";; ADDITIONAL RECORDS:\n");
340 if (!cp) 367 ErrorTest(cp);
341 return; 368 return;
369 trunc:
370 fprintf(file, "\n;; ...truncated\n");
371 return;
372 error:
373 fprintf(file, "\n;; ...malformed\n");
342} 374}
343 375
344char * 376void
345p_cdname(cp, msg, file) 377__fp_query(const u_char *msg, FILE *file)
346 char *cp, *msg; 378{
347 FILE *file; 379 fp_nquery(msg, PACKETSZ, file);
380}
381
382const u_char *
383__p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file)
348{ 384{
349 char name[MAXDNAME]; 385 char name[MAXDNAME];
350 int n; 386 int n;
351 387
352 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 388 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
353 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
354 return (NULL); 389 return (NULL);
355 if (name[0] == '\0') 390 if (name[0] == '\0')
356 putc('.', file); 391 putc('.', file);
@@ -359,55 +394,86 @@ p_cdname(cp, msg, file)
359 return (cp + n); 394 return (cp + n);
360} 395}
361 396
362char * 397const u_char *
363p_fqname(cp, msg, file) 398__p_cdname(const u_char *cp, const u_char *msg, FILE *file)
364 char *cp, *msg;
365 FILE *file;
366{ 399{
367 char name[MAXDNAME]; 400 return (p_cdnname(cp, msg, PACKETSZ, file));
368 int n, len; 401}
402
403
404/* Return a fully-qualified domain name from a compressed name (with
405 length supplied). */
406
407const u_char *
408__p_fqnname(const u_char *cp, const u_char *msg, int msglen, char *name, int namelen)
409{
410 int n, newlen;
369 411
370 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 412 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
371 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
372 return (NULL); 413 return (NULL);
373 if (name[0] == '\0') { 414 newlen = strlen(name);
374 putc('.', file); 415 if (newlen == 0 || name[newlen - 1] != '.') {
375 } else { 416 if (newlen + 1 >= namelen) /* Lack space for final dot */
376 fputs(name, file); 417 return (NULL);
377 if (name[strlen(name) - 1] != '.') 418 else
378 putc('.', file); 419 strlcpy(name + newlen, ".", namelen - newlen);
379 } 420 }
380 return (cp + n); 421 return (cp + n);
381} 422}
382 423
424/* XXX: the rest of these functions need to become length-limited, too. (vix)
425 */
426
427const u_char *
428__p_fqname(const u_char *cp, const u_char *msg, FILE *file)
429{
430 char name[MAXDNAME];
431 const u_char *n;
432
433 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
434 if (n == NULL)
435 return (NULL);
436 fputs(name, file);
437 return (n);
438}
439
383/* 440/*
384 * Print resource record fields in human readable form. 441 * Print resource record fields in human readable form.
385 */ 442 */
386char * 443const u_char *
387p_rr(cp, msg, file) 444__p_rr(const u_char *cp, const u_char *msg, FILE *file)
388 char *cp, *msg;
389 FILE *file;
390{ 445{
446 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
391 int type, class, dlen, n, c; 447 int type, class, dlen, n, c;
392 struct in_addr inaddr; 448 struct in_addr inaddr;
393 char *cp1, *cp2; 449 const u_char *cp1, *cp2;
394 u_int32_t tmpttl, t; 450 u_int32_t tmpttl, t;
395 int lcnt; 451 int lcnt;
452 u_int16_t keyflags;
453 char rrname[MAXDNAME]; /* The fqdn of this RR */
454 char base64_key[MAX_KEY_BASE64];
396 455
397 if ((cp = p_fqname(cp, msg, file)) == NULL) 456 if (_res_init(0) == -1) {
457 h_errno = NETDB_INTERNAL;
458 return (NULL);
459 }
460 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
461 if (!cp)
398 return (NULL); /* compression error */ 462 return (NULL); /* compression error */
399 type = _getshort(cp); 463 fputs(rrname, file);
400 cp += sizeof(u_int16_t); 464
401 class = _getshort(cp); 465 type = _getshort((u_char*)cp);
402 cp += sizeof(u_int16_t); 466 cp += INT16SZ;
403 tmpttl = _getlong(cp); 467 class = _getshort((u_char*)cp);
404 cp += sizeof(u_int32_t); 468 cp += INT16SZ;
405 dlen = _getshort(cp); 469 tmpttl = _getlong((u_char*)cp);
406 cp += sizeof(u_int16_t); 470 cp += INT32SZ;
471 dlen = _getshort((u_char*)cp);
472 cp += INT16SZ;
407 cp1 = cp; 473 cp1 = cp;
408 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 474 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_TTLID))
409 fprintf(file, "\t%lu", tmpttl); 475 fprintf(file, "\t%lu", (u_long)tmpttl);
410 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) 476 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_CLASS))
411 fprintf(file, "\t%s", __p_class(class)); 477 fprintf(file, "\t%s", __p_class(class));
412 fprintf(file, "\t%s", __p_type(type)); 478 fprintf(file, "\t%s", __p_type(type));
413 /* 479 /*
@@ -418,22 +484,22 @@ p_rr(cp, msg, file)
418 switch (class) { 484 switch (class) {
419 case C_IN: 485 case C_IN:
420 case C_HS: 486 case C_HS:
421 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 487 bcopy(cp, (char *)&inaddr, INADDRSZ);
422 if (dlen == 4) { 488 if (dlen == 4) {
423 fprintf(file,"\t%s", inet_ntoa(inaddr)); 489 fprintf(file, "\t%s", inet_ntoa(inaddr));
424 cp += dlen; 490 cp += dlen;
425 } else if (dlen == 7) { 491 } else if (dlen == 7) {
426 char *address; 492 char *address;
427 u_char protocol; 493 u_char protocol;
428 u_short port; 494 in_port_t port;
429 495
430 address = inet_ntoa(inaddr); 496 address = inet_ntoa(inaddr);
431 cp += sizeof(inaddr); 497 cp += INADDRSZ;
432 protocol = *(u_char*)cp; 498 protocol = *(u_char*)cp;
433 cp += sizeof(u_char); 499 cp += sizeof (u_char);
434 port = _getshort(cp); 500 port = _getshort((u_char*)cp);
435 cp += sizeof(u_int16_t); 501 cp += INT16SZ;
436 fprintf(file, "\t%s\t; proto %d, port %d", 502 fprintf(file, "\t%s\t; proto %u, port %u",
437 address, protocol, port); 503 address, protocol, port);
438 } 504 }
439 break; 505 break;
@@ -448,98 +514,205 @@ p_rr(cp, msg, file)
448 case T_NS: 514 case T_NS:
449 case T_PTR: 515 case T_PTR:
450 putc('\t', file); 516 putc('\t', file);
451 cp = p_fqname(cp, msg, file); 517 if ((cp = p_fqname(cp, msg, file)) == NULL)
518 return (NULL);
452 break; 519 break;
453 520
454 case T_HINFO: 521 case T_HINFO:
455 if (n = *cp++) { 522 case T_ISDN:
456 fprintf(file,"\t%.*s", n, cp); 523 cp2 = cp + dlen;
457 cp += n; 524 (void) fputs("\t\"", file);
525 if ((n = (unsigned char) *cp++) != 0) {
526 for (c = n; c > 0 && cp < cp2; c--) {
527 if (strchr("\n\"\\", *cp))
528 (void) putc('\\', file);
529 (void) putc(*cp++, file);
530 }
458 } 531 }
459 if (n = *cp++) { 532 putc('"', file);
460 fprintf(file,"\t%.*s", n, cp); 533 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
461 cp += n; 534 (void) fputs ("\t\"", file);
535 for (c = n; c > 0 && cp < cp2; c--) {
536 if (strchr("\n\"\\", *cp))
537 (void) putc('\\', file);
538 (void) putc(*cp++, file);
539 }
540 putc('"', file);
541 } else if (type == T_HINFO) {
542 (void) fputs("\"?\"", file);
543 fprintf(file, "\n;; *** Warning *** OS-type missing");
462 } 544 }
463 break; 545 break;
464 546
465 case T_SOA: 547 case T_SOA:
466 putc('\t', file); 548 putc('\t', file);
467 cp = p_fqname(cp, msg, file); /* origin */ 549 if ((cp = p_fqname(cp, msg, file)) == NULL)
550 return (NULL);
468 putc(' ', file); 551 putc(' ', file);
469 cp = p_fqname(cp, msg, file); /* mail addr */ 552 if ((cp = p_fqname(cp, msg, file)) == NULL)
553 return (NULL);
470 fputs(" (\n", file); 554 fputs(" (\n", file);
471 t = _getlong(cp); cp += sizeof(u_int32_t); 555 t = _getlong((u_char*)cp); cp += INT32SZ;
472 fprintf(file,"\t\t\t%lu\t; serial\n", t); 556 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
473 t = _getlong(cp); cp += sizeof(u_int32_t); 557 t = _getlong((u_char*)cp); cp += INT32SZ;
474 fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); 558 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
475 t = _getlong(cp); cp += sizeof(u_int32_t); 559 (u_long)t, __p_time(t));
476 fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); 560 t = _getlong((u_char*)cp); cp += INT32SZ;
477 t = _getlong(cp); cp += sizeof(u_int32_t); 561 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
478 fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); 562 (u_long)t, __p_time(t));
479 t = _getlong(cp); cp += sizeof(u_int32_t); 563 t = _getlong((u_char*)cp); cp += INT32SZ;
480 fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); 564 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
565 (u_long)t, __p_time(t));
566 t = _getlong((u_char*)cp); cp += INT32SZ;
567 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
568 (u_long)t, __p_time(t));
481 break; 569 break;
482 570
483 case T_MX: 571 case T_MX:
484 case T_AFSDB: 572 case T_AFSDB:
485 fprintf(file,"\t%d ", _getshort(cp)); 573 case T_RT:
486 cp += sizeof(u_int16_t); 574 fprintf(file, "\t%u ", _getshort((u_char*)cp));
487 cp = p_fqname(cp, msg, file); 575 cp += INT16SZ;
576 if ((cp = p_fqname(cp, msg, file)) == NULL)
577 return (NULL);
488 break; 578 break;
489 579
490 case T_TXT: 580 case T_PX:
581 fprintf(file, "\t%u ", _getshort((u_char*)cp));
582 cp += INT16SZ;
583 if ((cp = p_fqname(cp, msg, file)) == NULL)
584 return (NULL);
585 putc(' ', file);
586 if ((cp = p_fqname(cp, msg, file)) == NULL)
587 return (NULL);
588 break;
589
590 case T_X25:
591 cp2 = cp + dlen;
491 (void) fputs("\t\"", file); 592 (void) fputs("\t\"", file);
593 if ((n = (unsigned char) *cp++) != 0) {
594 for (c = n; c > 0 && cp < cp2; c--) {
595 if (strchr("\n\"\\", *cp))
596 (void) putc('\\', file);
597 (void) putc(*cp++, file);
598 }
599 }
600 putc('"', file);
601 break;
602
603 case T_TXT:
604 (void) putc('\t', file);
492 cp2 = cp1 + dlen; 605 cp2 = cp1 + dlen;
493 while (cp < cp2) { 606 while (cp < cp2) {
494 if (n = (unsigned char) *cp++) { 607 putc('"', file);
495 for (c = n; c > 0 && cp < cp2; c--) 608 if ((n = (unsigned char) *cp++)) {
496 if (*cp == '\n') { 609 for (c = n; c > 0 && cp < cp2; c--) {
497 (void) putc('\\', file); 610 if (strchr("\n\"\\", *cp))
498 (void) putc(*cp++, file); 611 (void) putc('\\', file);
499 } else 612 (void) putc(*cp++, file);
500 (void) putc(*cp++, file); 613 }
501 } 614 }
615 putc('"', file);
616 if (cp < cp2)
617 putc(' ', file);
502 } 618 }
503 putc('"', file); 619 break;
504 break; 620
621 case T_NSAP:
622 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
623 cp += dlen;
624 break;
625
626 case T_AAAA: {
627 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
628
629 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
630 cp += dlen;
631 break;
632 }
633
634 case T_LOC: {
635 char t[255];
636
637 fprintf(file, "\t%s", loc_ntoal(cp, t, sizeof t));
638 cp += dlen;
639 break;
640 }
641
642 case T_NAPTR: {
643 u_int order, preference;
644
645 order = _getshort(cp); cp += INT16SZ;
646 preference = _getshort(cp); cp += INT16SZ;
647 fprintf(file, "\t%u %u ",order, preference);
648 /* Flags */
649 n = *cp++;
650 fprintf(file,"\"%.*s\" ", (int)n, cp);
651 cp += n;
652 /* Service */
653 n = *cp++;
654 fprintf(file,"\"%.*s\" ", (int)n, cp);
655 cp += n;
656 /* Regexp */
657 n = *cp++;
658 fprintf(file,"\"%.*s\" ", (int)n, cp);
659 cp += n;
660 if ((cp = p_fqname(cp, msg, file)) == NULL)
661 return (NULL);
662 break;
663 }
664
665 case T_SRV: {
666 u_int priority, weight, port;
667
668 priority = _getshort(cp); cp += INT16SZ;
669 weight = _getshort(cp); cp += INT16SZ;
670 port = _getshort(cp); cp += INT16SZ;
671 fprintf(file, "\t%u %u %u ", priority, weight, port);
672 if ((cp = p_fqname(cp, msg, file)) == NULL)
673 return (NULL);
674 break;
675 }
505 676
506 case T_MINFO: 677 case T_MINFO:
507 case T_RP: 678 case T_RP:
508 putc('\t', file); 679 putc('\t', file);
509 cp = p_fqname(cp, msg, file); 680 if ((cp = p_fqname(cp, msg, file)) == NULL)
681 return (NULL);
510 putc(' ', file); 682 putc(' ', file);
511 cp = p_fqname(cp, msg, file); 683 if ((cp = p_fqname(cp, msg, file)) == NULL)
684 return (NULL);
512 break; 685 break;
513 686
514 case T_UINFO: 687 case T_UINFO:
515 putc('\t', file); 688 putc('\t', file);
516 fputs(cp, file); 689 fputs((char *)cp, file);
517 cp += dlen; 690 cp += dlen;
518 break; 691 break;
519 692
520 case T_UID: 693 case T_UID:
521 case T_GID: 694 case T_GID:
522 if (dlen == 4) { 695 if (dlen == 4) {
523 fprintf(file,"\t%u", _getlong(cp)); 696 fprintf(file, "\t%u", _getlong((u_char*)cp));
524 cp += sizeof(int32_t); 697 cp += INT32SZ;
525 } 698 }
526 break; 699 break;
527 700
528 case T_WKS: 701 case T_WKS:
529 if (dlen < sizeof(u_int32_t) + 1) 702 if (dlen < INT32SZ + 1)
530 break; 703 break;
531 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 704 bcopy(cp, (char *)&inaddr, INADDRSZ);
532 cp += sizeof(u_int32_t); 705 cp += INT32SZ;
533 fprintf(file, "\t%s %s ( ", 706 fprintf(file, "\t%s %s ( ",
534 inet_ntoa(inaddr), 707 inet_ntoa(inaddr),
535 deproto((int) *cp)); 708 deproto((int) *cp));
536 cp += sizeof(u_char); 709 cp += sizeof (u_char);
537 n = 0; 710 n = 0;
538 lcnt = 0; 711 lcnt = 0;
539 while (cp < cp1 + dlen) { 712 while (cp < cp1 + dlen) {
540 c = *cp++; 713 c = *cp++;
541 do { 714 do {
542 if (c & 0200) { 715 if (c & 0200) {
543 if (lcnt == 0) { 716 if (lcnt == 0) {
544 fputs("\n\t\t\t", file); 717 fputs("\n\t\t\t", file);
545 lcnt = 5; 718 lcnt = 5;
@@ -548,17 +721,84 @@ p_rr(cp, msg, file)
548 putc(' ', file); 721 putc(' ', file);
549 lcnt--; 722 lcnt--;
550 } 723 }
551 c <<= 1; 724 c <<= 1;
552 } while (++n & 07); 725 } while (++n & 07);
553 } 726 }
554 putc(')', file); 727 putc(')', file);
555 break; 728 break;
556 729
730 case T_KEY:
731 putc('\t', file);
732 keyflags = _getshort(cp);
733 cp += 2;
734 fprintf(file,"0x%04x", keyflags ); /* flags */
735 fprintf(file," %u", *cp++); /* protocol */
736 fprintf(file," %u (", *cp++); /* algorithm */
737
738 n = b64_ntop(cp, (cp1 + dlen) - cp,
739 base64_key, sizeof base64_key);
740 for (c = 0; c < n; ++c) {
741 if (0 == (c & 0x3F))
742 fprintf(file, "\n\t");
743 putc(base64_key[c], file); /* public key data */
744 }
745
746 fprintf(file, " )");
747 if (n < 0)
748 fprintf(file, "\t; BAD BASE64");
749 fflush(file);
750 cp = cp1 + dlen;
751 break;
752
753 case T_SIG:
754 case T_RRSIG:
755 type = _getshort((u_char*)cp);
756 cp += INT16SZ;
757 fprintf(file, " %s", p_type(type));
758 fprintf(file, "\t%u", *cp++); /* algorithm */
759 /* Check label value and print error if wrong. */
760 n = *cp++;
761 c = dn_count_labels (rrname);
762 if (n != c)
763 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
764 n, c);
765 /* orig ttl */
766 n = _getlong((u_char*)cp);
767 if (n != tmpttl)
768 fprintf(file, " %u", n);
769 cp += INT32SZ;
770 /* sig expire */
771 fprintf(file, " (\n\t%s",
772 __p_secstodate(_getlong((u_char*)cp)));
773 cp += INT32SZ;
774 /* time signed */
775 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
776 cp += INT32SZ;
777 /* sig footprint */
778 fprintf(file," %u ", _getshort((u_char*)cp));
779 cp += INT16SZ;
780 /* signer's name */
781 cp = p_fqname(cp, msg, file);
782 n = b64_ntop(cp, (cp1 + dlen) - cp,
783 base64_key, sizeof base64_key);
784 for (c = 0; c < n; c++) {
785 if (0 == (c & 0x3F))
786 fprintf (file, "\n\t");
787 putc(base64_key[c], file); /* signature */
788 }
789 /* Clean up... */
790 fprintf(file, " )");
791 if (n < 0)
792 fprintf(file, "\t; BAD BASE64");
793 fflush(file);
794 cp = cp1+dlen;
795 break;
796
557#ifdef ALLOW_T_UNSPEC 797#ifdef ALLOW_T_UNSPEC
558 case T_UNSPEC: 798 case T_UNSPEC:
559 { 799 {
560 int NumBytes = 8; 800 int NumBytes = 8;
561 char *DataPtr; 801 u_char *DataPtr;
562 int i; 802 int i;
563 803
564 if (dlen < NumBytes) NumBytes = dlen; 804 if (dlen < NumBytes) NumBytes = dlen;
@@ -572,7 +812,7 @@ p_rr(cp, msg, file)
572#endif /* ALLOW_T_UNSPEC */ 812#endif /* ALLOW_T_UNSPEC */
573 813
574 default: 814 default:
575 fprintf(file,"\t?%d?", type); 815 fprintf(file, "\t?%d?", type);
576 cp += dlen; 816 cp += dlen;
577 } 817 }
578#if 0 818#if 0
@@ -581,136 +821,91 @@ p_rr(cp, msg, file)
581 putc('\n', file); 821 putc('\n', file);
582#endif 822#endif
583 if (cp - cp1 != dlen) { 823 if (cp - cp1 != dlen) {
584 fprintf(file,";; packet size error (found %d, dlen was %d)\n", 824 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
585 cp - cp1, dlen); 825 (long)(cp - cp1), dlen);
586 cp = NULL; 826 cp = NULL;
587 } 827 }
588 return (cp); 828 return (cp);
589} 829}
590 830
591static char nbuf[40]; 831int
592 832__sym_ston(const struct res_sym *syms, char *name, int *success)
593/*
594 * Return a string for the type
595 */
596char *
597__p_type(type)
598 int type;
599{ 833{
600 switch (type) { 834 for (; syms->name != 0; syms++) {
601 case T_A: 835 if (strcasecmp (name, syms->name) == 0) {
602 return("A"); 836 if (success)
603 case T_NS: /* authoritative server */ 837 *success = 1;
604 return("NS"); 838 return (syms->number);
605 case T_CNAME: /* canonical name */ 839 }
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 } 840 }
841 if (success)
842 *success = 0;
843 return (syms->number); /* The default value. */
656} 844}
657 845
658/* 846
659 * Return a mnemonic for class 847const char *
660 */ 848__sym_ntop(const struct res_sym *syms, int number, int *success)
661char *
662__p_class(class)
663 int class;
664{ 849{
850 static char unname[20];
665 851
666 switch (class) { 852 for (; syms->name != 0; syms++) {
667 case C_IN: /* internet class */ 853 if (number == syms->number) {
668 return("IN"); 854 if (success)
669 case C_HS: /* hesiod class */ 855 *success = 1;
670 return("HS"); 856 return (syms->humanname);
671 case C_ANY: /* matches any class */ 857 }
672 return("ANY");
673 default:
674 (void)sprintf(nbuf, "%d", class);
675 return(nbuf);
676 } 858 }
859 snprintf(unname, sizeof unname, "%d", number);
860 if (success)
861 *success = 0;
862 return (unname);
677} 863}
678 864
679/* 865/*
680 * Return a mnemonic for an option 866 * Return a mnemonic for an option
681 */ 867 */
682static char * 868const char *
683p_option(option) 869__p_option(u_long option)
684 u_int32_t option;
685{ 870{
871 static char nbuf[40];
872
686 switch (option) { 873 switch (option) {
687 case RES_INIT: return "init"; 874 case RES_INIT: return "init";
688 case RES_DEBUG: return "debug"; 875 case RES_DEBUG: return "debug";
689 case RES_AAONLY: return "aaonly"; 876 case RES_AAONLY: return "aaonly(unimpl)";
690 case RES_USEVC: return "usevc"; 877 case RES_USEVC: return "usevc";
691 case RES_PRIMARY: return "primry"; 878 case RES_PRIMARY: return "primry(unimpl)";
692 case RES_IGNTC: return "igntc"; 879 case RES_IGNTC: return "igntc";
693 case RES_RECURSE: return "recurs"; 880 case RES_RECURSE: return "recurs";
694 case RES_DEFNAMES: return "defnam"; 881 case RES_DEFNAMES: return "defnam";
695 case RES_STAYOPEN: return "styopn"; 882 case RES_STAYOPEN: return "styopn";
696 case RES_DNSRCH: return "dnsrch"; 883 case RES_DNSRCH: return "dnsrch";
697 default: sprintf(nbuf, "?0x%x?", option); return nbuf; 884 case RES_INSECURE1: return "insecure1";
885 case RES_INSECURE2: return "insecure2";
886 case RES_USE_INET6: return "inet6";
887 case RES_USE_EDNS0: return "edns0";
888 default:
889 snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option);
890 return (nbuf);
698 } 891 }
699} 892}
700 893
701/* 894/*
702 * Return a mnemonic for a time to live 895 * Return a mnemonic for a time to live
703 */ 896 */
704char * 897const char *
705__p_time(value) 898p_time(u_int32_t value)
706 u_int32_t value;
707{ 899{
900 static char nbuf[40];
901 char *ebuf;
708 int secs, mins, hours, days; 902 int secs, mins, hours, days;
709 register char *p; 903 char *p;
904 int tmp;
710 905
711 if (value == 0) { 906 if (value == 0) {
712 strcpy(nbuf, "0 secs"); 907 strlcpy(nbuf, "0 secs", sizeof nbuf);
713 return(nbuf); 908 return (nbuf);
714 } 909 }
715 910
716 secs = value % 60; 911 secs = value % 60;
@@ -724,26 +919,477 @@ __p_time(value)
724 919
725#define PLURALIZE(x) x, (x == 1) ? "" : "s" 920#define PLURALIZE(x) x, (x == 1) ? "" : "s"
726 p = nbuf; 921 p = nbuf;
922 ebuf = nbuf + sizeof(nbuf);
727 if (days) { 923 if (days) {
728 (void)sprintf(p, "%d day%s", PLURALIZE(days)); 924 if ((tmp = snprintf(p, ebuf - p, "%d day%s",
729 while (*++p); 925 PLURALIZE(days))) >= ebuf - p || tmp < 0)
926 goto full;
927 p += tmp;
730 } 928 }
731 if (hours) { 929 if (hours) {
732 if (days) 930 if (days)
733 *p++ = ' '; 931 *p++ = ' ';
734 (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); 932 if (p >= ebuf)
735 while (*++p); 933 goto full;
934 if ((tmp = snprintf(p, ebuf - p, "%d hour%s",
935 PLURALIZE(hours))) >= ebuf - p || tmp < 0)
936 goto full;
937 p += tmp;
736 } 938 }
737 if (mins) { 939 if (mins) {
738 if (days || hours) 940 if (days || hours)
739 *p++ = ' '; 941 *p++ = ' ';
740 (void)sprintf(p, "%d min%s", PLURALIZE(mins)); 942 if (p >= ebuf)
741 while (*++p); 943 goto full;
944 if ((tmp = snprintf(p, ebuf - p, "%d min%s",
945 PLURALIZE(mins))) >= ebuf - p || tmp < 0)
946 goto full;
947 p += tmp;
742 } 948 }
743 if (secs || ! (days || hours || mins)) { 949 if (secs || ! (days || hours || mins)) {
744 if (days || hours || mins) 950 if (days || hours || mins)
745 *p++ = ' '; 951 *p++ = ' ';
746 (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); 952 if (p >= ebuf)
953 goto full;
954 if ((tmp = snprintf(p, ebuf - p, "%d sec%s",
955 PLURALIZE(secs))) >= ebuf - p || tmp < 0)
956 goto full;
747 } 957 }
748 return(nbuf); 958 return (nbuf);
959full:
960 p = nbuf + sizeof(nbuf) - 4;
961 *p++ = '.';
962 *p++ = '.';
963 *p++ = '.';
964 *p++ = '\0';
965 return (nbuf);
966}
967
968/*
969 * routines to convert between on-the-wire RR format and zone file format.
970 * Does not contain conversion to/from decimal degrees; divide or multiply
971 * by 60*60*1000 for that.
972 */
973
974static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
975 1000000,10000000,100000000,1000000000};
976
977/* takes an XeY precision/size value, returns a string representation. */
978static const char *
979precsize_ntoa(u_int8_t prec)
980{
981 static char retbuf[sizeof "90000000.00"];
982 unsigned long val;
983 int mantissa, exponent;
984
985 mantissa = (int)((prec >> 4) & 0x0f) % 10;
986 exponent = (int)((prec >> 0) & 0x0f) % 10;
987
988 val = mantissa * poweroften[exponent];
989
990 (void) snprintf(retbuf, sizeof retbuf, "%ld.%.2ld", val/100, val%100);
991 return (retbuf);
992}
993
994/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
995static u_int8_t
996precsize_aton(char **strptr)
997{
998 unsigned int mval = 0, cmval = 0;
999 u_int8_t retval = 0;
1000 char *cp;
1001 int exponent;
1002 int mantissa;
1003
1004 cp = *strptr;
1005
1006 while (isdigit(*cp))
1007 mval = mval * 10 + (*cp++ - '0');
1008
1009 if (*cp == '.') { /* centimeters */
1010 cp++;
1011 if (isdigit(*cp)) {
1012 cmval = (*cp++ - '0') * 10;
1013 if (isdigit(*cp)) {
1014 cmval += (*cp++ - '0');
1015 }
1016 }
1017 }
1018 cmval = (mval * 100) + cmval;
1019
1020 for (exponent = 0; exponent < 9; exponent++)
1021 if (cmval < poweroften[exponent+1])
1022 break;
1023
1024 mantissa = cmval / poweroften[exponent];
1025 if (mantissa > 9)
1026 mantissa = 9;
1027
1028 retval = (mantissa << 4) | exponent;
1029
1030 *strptr = cp;
1031
1032 return (retval);
1033}
1034
1035/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1036static u_int32_t
1037latlon2ul(char **latlonstrptr, int *which)
1038{
1039 char *cp;
1040 u_int32_t retval;
1041 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1042
1043 cp = *latlonstrptr;
1044
1045 while (isdigit(*cp))
1046 deg = deg * 10 + (*cp++ - '0');
1047
1048 while (isspace(*cp))
1049 cp++;
1050
1051 if (!(isdigit(*cp)))
1052 goto fndhemi;
1053
1054 while (isdigit(*cp))
1055 min = min * 10 + (*cp++ - '0');
1056
1057 while (isspace(*cp))
1058 cp++;
1059
1060 if (!(isdigit(*cp)))
1061 goto fndhemi;
1062
1063 while (isdigit(*cp))
1064 secs = secs * 10 + (*cp++ - '0');
1065
1066 if (*cp == '.') { /* decimal seconds */
1067 cp++;
1068 if (isdigit(*cp)) {
1069 secsfrac = (*cp++ - '0') * 100;
1070 if (isdigit(*cp)) {
1071 secsfrac += (*cp++ - '0') * 10;
1072 if (isdigit(*cp)) {
1073 secsfrac += (*cp++ - '0');
1074 }
1075 }
1076 }
1077 }
1078
1079 while (!isspace(*cp)) /* if any trailing garbage */
1080 cp++;
1081
1082 while (isspace(*cp))
1083 cp++;
1084
1085 fndhemi:
1086 switch (*cp) {
1087 case 'N': case 'n':
1088 case 'E': case 'e':
1089 retval = ((unsigned)1<<31)
1090 + (((((deg * 60) + min) * 60) + secs) * 1000)
1091 + secsfrac;
1092 break;
1093 case 'S': case 's':
1094 case 'W': case 'w':
1095 retval = ((unsigned)1<<31)
1096 - (((((deg * 60) + min) * 60) + secs) * 1000)
1097 - secsfrac;
1098 break;
1099 default:
1100 retval = 0; /* invalid value -- indicates error */
1101 break;
1102 }
1103
1104 switch (*cp) {
1105 case 'N': case 'n':
1106 case 'S': case 's':
1107 *which = 1; /* latitude */
1108 break;
1109 case 'E': case 'e':
1110 case 'W': case 'w':
1111 *which = 2; /* longitude */
1112 break;
1113 default:
1114 *which = 0; /* error */
1115 break;
1116 }
1117
1118 cp++; /* skip the hemisphere */
1119
1120 while (!isspace(*cp)) /* if any trailing garbage */
1121 cp++;
1122
1123 while (isspace(*cp)) /* move to next field */
1124 cp++;
1125
1126 *latlonstrptr = cp;
1127
1128 return (retval);
1129}
1130
1131/* converts a zone file representation in a string to an RDATA on-the-wire
1132 * representation. */
1133int
1134loc_aton(const char *ascii, u_char *binary)
1135{
1136 const char *maxcp;
1137 u_char *bcp;
1138 char *cp;
1139
1140 u_int32_t latit = 0, longit = 0, alt = 0;
1141 u_int32_t lltemp1 = 0, lltemp2 = 0;
1142 int altmeters = 0, altfrac = 0, altsign = 1;
1143 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1144 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1145 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1146 int which1 = 0, which2 = 0;
1147
1148 cp = (char *)ascii;
1149 maxcp = cp + strlen(ascii);
1150
1151 lltemp1 = latlon2ul(&cp, &which1);
1152
1153 lltemp2 = latlon2ul(&cp, &which2);
1154
1155 switch (which1 + which2) {
1156 case 3: /* 1 + 2, the only valid combination */
1157 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1158 latit = lltemp1;
1159 longit = lltemp2;
1160 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1161 longit = lltemp1;
1162 latit = lltemp2;
1163 } else { /* some kind of brokenness */
1164 return (0);
1165 }
1166 break;
1167 default: /* we didn't get one of each */
1168 return (0);
1169 }
1170
1171 /* altitude */
1172 if (*cp == '-') {
1173 altsign = -1;
1174 cp++;
1175 }
1176
1177 if (*cp == '+')
1178 cp++;
1179
1180 while (isdigit(*cp))
1181 altmeters = altmeters * 10 + (*cp++ - '0');
1182
1183 if (*cp == '.') { /* decimal meters */
1184 cp++;
1185 if (isdigit(*cp)) {
1186 altfrac = (*cp++ - '0') * 10;
1187 if (isdigit(*cp)) {
1188 altfrac += (*cp++ - '0');
1189 }
1190 }
1191 }
1192
1193 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1194
1195 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1196 cp++;
1197
1198 while (isspace(*cp) && (cp < maxcp))
1199 cp++;
1200
1201 if (cp >= maxcp)
1202 goto defaults;
1203
1204 siz = precsize_aton(&cp);
1205
1206 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1207 cp++;
1208
1209 while (isspace(*cp) && (cp < maxcp))
1210 cp++;
1211
1212 if (cp >= maxcp)
1213 goto defaults;
1214
1215 hp = precsize_aton(&cp);
1216
1217 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1218 cp++;
1219
1220 while (isspace(*cp) && (cp < maxcp))
1221 cp++;
1222
1223 if (cp >= maxcp)
1224 goto defaults;
1225
1226 vp = precsize_aton(&cp);
1227
1228 defaults:
1229
1230 bcp = binary;
1231 *bcp++ = (u_int8_t) 0; /* version byte */
1232 *bcp++ = siz;
1233 *bcp++ = hp;
1234 *bcp++ = vp;
1235 PUTLONG(latit,bcp);
1236 PUTLONG(longit,bcp);
1237 PUTLONG(alt,bcp);
1238
1239 return (16); /* size of RR in octets */
1240}
1241
1242const char *
1243loc_ntoa(const u_char *binary, char *ascii)
1244{
1245 return loc_ntoal(binary, ascii, 255);
1246}
1247
1248/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1249static const char *
1250loc_ntoal(const u_char *binary, char *ascii, int ascii_len)
1251{
1252 static char *error = "?";
1253 const u_char *cp = binary;
1254
1255 int latdeg, latmin, latsec, latsecfrac;
1256 int longdeg, longmin, longsec, longsecfrac;
1257 char northsouth, eastwest;
1258 int altmeters, altfrac, altsign;
1259
1260 const int referencealt = 100000 * 100;
1261
1262 int32_t latval, longval, altval;
1263 u_int32_t templ;
1264 u_int8_t sizeval, hpval, vpval, versionval;
1265
1266 char *sizestr, *hpstr, *vpstr;
1267
1268 versionval = *cp++;
1269
1270 if (versionval) {
1271 snprintf(ascii, ascii_len, "; error: unknown LOC RR version");
1272 return (ascii);
1273 }
1274
1275 sizeval = *cp++;
1276
1277 hpval = *cp++;
1278 vpval = *cp++;
1279
1280 GETLONG(templ, cp);
1281 latval = (templ - ((unsigned)1<<31));
1282
1283 GETLONG(templ, cp);
1284 longval = (templ - ((unsigned)1<<31));
1285
1286 GETLONG(templ, cp);
1287 if (templ < referencealt) { /* below WGS 84 spheroid */
1288 altval = referencealt - templ;
1289 altsign = -1;
1290 } else {
1291 altval = templ - referencealt;
1292 altsign = 1;
1293 }
1294
1295 if (latval < 0) {
1296 northsouth = 'S';
1297 latval = -latval;
1298 } else
1299 northsouth = 'N';
1300
1301 latsecfrac = latval % 1000;
1302 latval = latval / 1000;
1303 latsec = latval % 60;
1304 latval = latval / 60;
1305 latmin = latval % 60;
1306 latval = latval / 60;
1307 latdeg = latval;
1308
1309 if (longval < 0) {
1310 eastwest = 'W';
1311 longval = -longval;
1312 } else
1313 eastwest = 'E';
1314
1315 longsecfrac = longval % 1000;
1316 longval = longval / 1000;
1317 longsec = longval % 60;
1318 longval = longval / 60;
1319 longmin = longval % 60;
1320 longval = longval / 60;
1321 longdeg = longval;
1322
1323 altfrac = altval % 100;
1324 altmeters = (altval / 100) * altsign;
1325
1326 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1327 sizestr = error;
1328 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1329 hpstr = error;
1330 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1331 vpstr = error;
1332
1333 snprintf(ascii, ascii_len,
1334 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1335 latdeg, latmin, latsec, latsecfrac, northsouth,
1336 longdeg, longmin, longsec, longsecfrac, eastwest,
1337 altmeters, altfrac, sizestr, hpstr, vpstr);
1338
1339 if (sizestr != error)
1340 free(sizestr);
1341 if (hpstr != error)
1342 free(hpstr);
1343 if (vpstr != error)
1344 free(vpstr);
1345
1346 return (ascii);
1347}
1348
1349
1350/* Return the number of DNS hierarchy levels in the name. */
1351int
1352__dn_count_labels(char *name)
1353{
1354 int i, len, count;
1355
1356 len = strlen(name);
1357
1358 for(i = 0, count = 0; i < len; i++) {
1359 if (name[i] == '.')
1360 count++;
1361 }
1362
1363 /* don't count initial wildcard */
1364 if (name[0] == '*')
1365 if (count)
1366 count--;
1367
1368 /* don't count the null label for root. */
1369 /* if terminating '.' not found, must adjust */
1370 /* count to include last label */
1371 if (len > 0 && name[len-1] != '.')
1372 count++;
1373 return (count);
1374}
1375
1376
1377/*
1378 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1379 * SIG records are required to be printed like this, by the Secure DNS RFC.
1380 */
1381char *
1382__p_secstodate (long unsigned int secs)
1383{
1384 static char output[15]; /* YYYYMMDDHHMMSS and null */
1385 time_t clock = secs;
1386 struct tm *time;
1387
1388 time = gmtime(&clock);
1389 time->tm_year += 1900;
1390 time->tm_mon += 1;
1391 snprintf(output, sizeof output, "%04d%02d%02d%02d%02d%02d",
1392 time->tm_year, time->tm_mon, time->tm_mday,
1393 time->tm_hour, time->tm_min, time->tm_sec);
1394 return (output);
749} 1395}
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 */
89const 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 */
103const 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
153const 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 */
175const 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 */
184const 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
index 33cc8d39f1..42d3b3ca1e 100644
--- a/src/lib/libc/net/res_init.c
+++ b/src/lib/libc/net/res_init.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $ */ 1/* $OpenBSD: res_init.c,v 1.37 2008/08/15 14:57:20 djm Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
4 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -53,80 +51,199 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
56#if defined(LIBC_SCCS) && !defined(lint) 54#ifndef INET6
57#if 0 55#define INET6
58static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
59static char rcsid[] = "$Id: res_init.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static char rcsid[] = "$NetBSD: res_init.c,v 1.8 1995/06/03 22:33:36 mycroft Exp $";
62#endif 56#endif
63#endif /* LIBC_SCCS and not lint */
64 57
58#include <sys/types.h>
65#include <sys/param.h> 59#include <sys/param.h>
66#include <sys/socket.h> 60#include <sys/socket.h>
61#include <sys/time.h>
62#include <sys/stat.h>
67#include <netinet/in.h> 63#include <netinet/in.h>
68#include <arpa/inet.h> 64#include <arpa/inet.h>
69#include <arpa/nameser.h> 65#include <arpa/nameser.h>
66
67#include <stdio.h>
68#include <ctype.h>
70#include <resolv.h> 69#include <resolv.h>
71#include <unistd.h> 70#include <unistd.h>
72#include <stdio.h>
73#include <stdlib.h> 71#include <stdlib.h>
74#include <string.h> 72#include <string.h>
73#ifdef INET6
74#include <netdb.h>
75#endif /* INET6 */
75 76
76static void res_setoptions __P((char *, char *)); 77#include "thread_private.h"
77static u_int32_t net_mask __P((struct in_addr)); 78
79/*-------------------------------------- info about "sortlist" --------------
80 * Marc Majka 1994/04/16
81 * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
82 *
83 * NetInfo resolver configuration directory support.
84 *
85 * Allow a NetInfo directory to be created in the hierarchy which
86 * contains the same information as the resolver configuration file.
87 *
88 * - The local domain name is stored as the value of the "domain" property.
89 * - The Internet address(es) of the name server(s) are stored as values
90 * of the "nameserver" property.
91 * - The name server addresses are stored as values of the "nameserver"
92 * property.
93 * - The search list for host-name lookup is stored as values of the
94 * "search" property.
95 * - The sortlist comprised of IP address netmask pairs are stored as
96 * values of the "sortlist" property. The IP address and optional netmask
97 * should be separated by a slash (/) or ampersand (&) character.
98 * - Internal resolver variables can be set from the value of the "options"
99 * property.
100 */
101
102static void res_setoptions(char *, char *);
103
104#ifdef RESOLVSORT
105static const char sort_mask[] = "/&";
106#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
107static u_int32_t net_mask(struct in_addr);
108#endif
78 109
79/* 110/*
80 * Resolver state default settings 111 * Resolver state default settings.
81 */ 112 */
113void *__THREAD_NAME(_res);
114
115struct __res_state _res
116# if defined(__BIND_RES_TEXT)
117 = { RES_TIMEOUT, } /* Motorola, et al. */
118# endif
119 ;
120#ifdef INET6
121void *__THREAD_NAME(_res_ext);
122
123struct __res_state_ext _res_ext;
124#endif /* INET6 */
82 125
83struct __res_state _res = { 126int __res_chktime = 30;
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 127
90/* 128/*
91 * Set up default settings. If the configuration file exist, the values 129 * Set up default settings. If the configuration file exist, the values
92 * there will have precedence. Otherwise, the server address is set to 130 * there will have precedence. Otherwise, the server address is set to
93 * INADDR_ANY and the default domain name comes from the gethostname(). 131 * INADDR_ANY and the default domain name comes from the gethostname().
94 * 132 *
95 * The configuration file should only be used if you want to redefine your 133 * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
96 * domain or run without a server on your machine. 134 * rather than INADDR_ANY ("0.0.0.0") as the default name server address
135 * since it was noted that INADDR_ANY actually meant ``the first interface
136 * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
137 * it had to be "up" in order for you to reach your own name server. It
138 * was later decided that since the recommended practice is to always
139 * install local static routes through 127.0.0.1 for all your network
140 * interfaces, that we could solve this problem without a code change.
141 *
142 * The configuration file should always be used, since it is the only way
143 * to specify a default domain. If you are running a server on your local
144 * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
145 * in the configuration file.
97 * 146 *
98 * Return 0 if completes successfully, -1 on error 147 * Return 0 if completes successfully, -1 on error
99 */ 148 */
100res_init() 149int
150res_init(void)
151{
152
153 return (_res_init(1));
154}
155
156int
157_res_init(int usercall)
101{ 158{
102 register FILE *fp; 159 struct stat sb;
103 register char *cp, **pp, *net; 160 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
104 register int n; 161#ifdef INET6
105 char buf[BUFSIZ], buf2[BUFSIZ]; 162 struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
163 &_res_ext);
164#endif
165 FILE *fp;
166 char *cp, **pp;
167 int n;
168 char buf[BUFSIZ];
106 int nserv = 0; /* number of nameserver records read from file */ 169 int nserv = 0; /* number of nameserver records read from file */
107 int haveenv = 0; 170 int haveenv = 0;
108 int havesearch = 0; 171 int havesearch = 0;
172 size_t len;
173#ifdef RESOLVSORT
109 int nsort = 0; 174 int nsort = 0;
110 u_long mask; 175 char *net;
176#endif
177#ifndef RFC1535
178 int dots;
179#endif
180
181 if (!usercall && _resp->options & RES_INIT &&
182 _resp->reschktime >= time(NULL))
183 return (0);
184 _resp->reschktime = time(NULL) + __res_chktime;
185 if (stat(_PATH_RESCONF, &sb) != -1) {
186 if (!usercall && timespeccmp(&sb.st_mtimespec,
187 &_resp->restimespec, ==))
188 return (0);
189 else
190 _resp->restimespec = sb.st_mtimespec;
191 } else {
192 /*
193 * Lost the file, in chroot?
194 * Don't trash settings
195 */
196 if (!usercall && timespecisset(&_resp->restimespec))
197 return (0);
198 }
199
200
201 /*
202 * These three fields used to be statically initialized. This made
203 * it hard to use this code in a shared library. It is necessary,
204 * now that we're doing dynamic initialization here, that we preserve
205 * the old semantics: if an application modifies one of these three
206 * fields of _res before res_init() is called, res_init() will not
207 * alter them. Of course, if an application is setting them to
208 * _zero_ before calling res_init(), hoping to override what used
209 * to be the static default, we can't detect it and unexpected results
210 * will follow. Zero for any of these fields would make no sense,
211 * so one can safely assume that the applications were already getting
212 * unexpected results.
213 *
214 * _res.options is tricky since some apps were known to diddle the bits
215 * before res_init() was first called. We can't replicate that semantic
216 * with dynamic initialization (they may have turned bits off that are
217 * set in RES_DEFAULT). Our solution is to declare such applications
218 * "broken". They could fool us by setting RES_INIT but none do (yet).
219 */
220 if (!_resp->retrans)
221 _resp->retrans = RES_TIMEOUT;
222 if (!_resp->retry)
223 _resp->retry = 4;
224 if (!(_resp->options & RES_INIT))
225 _resp->options = RES_DEFAULT;
111 226
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 227#ifdef USELOOPBACK
116 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); 228 _resp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
117#else 229#else
118 _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 230 _resp->nsaddr.sin_addr.s_addr = INADDR_ANY;
231#endif
232 _resp->nsaddr.sin_family = AF_INET;
233 _resp->nsaddr.sin_port = htons(NAMESERVER_PORT);
234 _resp->nsaddr.sin_len = sizeof(struct sockaddr_in);
235#ifdef INET6
236 if (sizeof(_res_extp->nsaddr) >= _resp->nsaddr.sin_len)
237 memcpy(&_res_extp->nsaddr, &_resp->nsaddr, _resp->nsaddr.sin_len);
119#endif 238#endif
120 _res.nscount = 1; 239 _resp->nscount = 1;
121 _res.ndots = 1; 240 _resp->ndots = 1;
122 _res.pfcode = 0; 241 _resp->pfcode = 0;
123 strncpy(_res.lookups, "f", sizeof _res.lookups); 242 strlcpy(_resp->lookups, "f", sizeof _resp->lookups);
124 243
125 /* Allow user to override the local domain definition */ 244 /* Allow user to override the local domain definition */
126 if ((cp = getenv("LOCALDOMAIN")) != NULL) { 245 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
127 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 246 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
128 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
129 *cp = '\0';
130 haveenv++; 247 haveenv++;
131 248
132 /* 249 /*
@@ -136,11 +253,11 @@ res_init()
136 * one that they want to use as an individual (even more 253 * one that they want to use as an individual (even more
137 * important now that the rfc1535 stuff restricts searches) 254 * important now that the rfc1535 stuff restricts searches)
138 */ 255 */
139 cp = _res.defdname; 256 cp = _resp->defdname;
140 pp = _res.dnsrch; 257 pp = _resp->dnsrch;
141 *pp++ = cp; 258 *pp++ = cp;
142 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 259 for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
143 if (*cp == '\n') /* silly backwards compat */ 260 if (*cp == '\n') /* silly backwards compat */
144 break; 261 break;
145 else if (*cp == ' ' || *cp == '\t') { 262 else if (*cp == ' ' || *cp == '\t') {
146 *cp = 0; 263 *cp = 0;
@@ -158,16 +275,29 @@ res_init()
158 *pp++ = 0; 275 *pp++ = 0;
159 } 276 }
160 277
278#define MATCH(line, name) \
279 (!strncmp(line, name, sizeof(name) - 1) && \
280 (line[sizeof(name) - 1] == ' ' || \
281 line[sizeof(name) - 1] == '\t'))
282
161 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 283 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
162 strncpy(_res.lookups, "bf", sizeof _res.lookups); 284 strlcpy(_resp->lookups, "bf", sizeof _resp->lookups);
163 285
164 /* read the config file */ 286 /* read the config file */
165 while (fgets(buf, sizeof(buf), fp) != NULL) { 287 buf[0] = '\0';
288 while ((cp = fgetln(fp, &len)) != NULL) {
289 /* skip lines that are too long */
290 if (len >= sizeof(buf))
291 continue;
292 (void)memcpy(buf, cp, len);
293 buf[len] = '\0';
166 /* skip comments */ 294 /* skip comments */
167 if ((*buf == ';') || (*buf == '#')) 295 if ((cp = strpbrk(buf, ";#")) != NULL)
296 *cp = '\0';
297 if (buf[0] == '\0')
168 continue; 298 continue;
169 /* read default domain name */ 299 /* read default domain name */
170 if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 300 if (MATCH(buf, "domain")) {
171 if (haveenv) /* skip if have from environ */ 301 if (haveenv) /* skip if have from environ */
172 continue; 302 continue;
173 cp = buf + sizeof("domain") - 1; 303 cp = buf + sizeof("domain") - 1;
@@ -175,18 +305,17 @@ res_init()
175 cp++; 305 cp++;
176 if ((*cp == '\0') || (*cp == '\n')) 306 if ((*cp == '\0') || (*cp == '\n'))
177 continue; 307 continue;
178 (void)strncpy(_res.defdname, cp, 308 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
179 sizeof(_res.defdname) - 1); 309 if ((cp = strpbrk(_resp->defdname, " \t\n")) != NULL)
180 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
181 *cp = '\0'; 310 *cp = '\0';
182 havesearch = 0; 311 havesearch = 0;
183 continue; 312 continue;
184 } 313 }
185 /* lookup types */ 314 /* lookup types */
186 if (!strncmp(buf, "lookup", sizeof("lookup") -1)) { 315 if (MATCH(buf, "lookup")) {
187 char *sp = NULL; 316 char *sp = NULL;
188 317
189 bzero(_res.lookups, sizeof _res.lookups); 318 bzero(_resp->lookups, sizeof _resp->lookups);
190 cp = buf + sizeof("lookup") - 1; 319 cp = buf + sizeof("lookup") - 1;
191 for (n = 0;; cp++) { 320 for (n = 0;; cp++) {
192 if (n == MAXDNSLUS) 321 if (n == MAXDNSLUS)
@@ -194,14 +323,14 @@ res_init()
194 if ((*cp == '\0') || (*cp == '\n')) { 323 if ((*cp == '\0') || (*cp == '\n')) {
195 if (sp) { 324 if (sp) {
196 if (*sp=='y' || *sp=='b' || *sp=='f') 325 if (*sp=='y' || *sp=='b' || *sp=='f')
197 _res.lookups[n++] = *sp; 326 _resp->lookups[n++] = *sp;
198 sp = NULL; 327 sp = NULL;
199 } 328 }
200 break; 329 break;
201 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) { 330 } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
202 if (sp) { 331 if (sp) {
203 if (*sp=='y' || *sp=='b' || *sp=='f') 332 if (*sp=='y' || *sp=='b' || *sp=='f')
204 _res.lookups[n++] = *sp; 333 _resp->lookups[n++] = *sp;
205 sp = NULL; 334 sp = NULL;
206 } 335 }
207 } else if (sp == NULL) 336 } else if (sp == NULL)
@@ -210,7 +339,7 @@ res_init()
210 continue; 339 continue;
211 } 340 }
212 /* set search list */ 341 /* set search list */
213 if (!strncmp(buf, "search", sizeof("search") - 1)) { 342 if (MATCH(buf, "search")) {
214 if (haveenv) /* skip if have from environ */ 343 if (haveenv) /* skip if have from environ */
215 continue; 344 continue;
216 cp = buf + sizeof("search") - 1; 345 cp = buf + sizeof("search") - 1;
@@ -218,18 +347,17 @@ res_init()
218 cp++; 347 cp++;
219 if ((*cp == '\0') || (*cp == '\n')) 348 if ((*cp == '\0') || (*cp == '\n'))
220 continue; 349 continue;
221 (void)strncpy(_res.defdname, cp, 350 strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
222 sizeof(_res.defdname) - 1); 351 if ((cp = strchr(_resp->defdname, '\n')) != NULL)
223 if ((cp = strchr(_res.defdname, '\n')) != NULL)
224 *cp = '\0'; 352 *cp = '\0';
225 /* 353 /*
226 * Set search list to be blank-separated strings 354 * Set search list to be blank-separated strings
227 * on rest of line. 355 * on rest of line.
228 */ 356 */
229 cp = _res.defdname; 357 cp = _resp->defdname;
230 pp = _res.dnsrch; 358 pp = _resp->dnsrch;
231 *pp++ = cp; 359 *pp++ = cp;
232 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 360 for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
233 if (*cp == ' ' || *cp == '\t') { 361 if (*cp == ' ' || *cp == '\t') {
234 *cp = 0; 362 *cp = 0;
235 n = 1; 363 n = 1;
@@ -247,130 +375,274 @@ res_init()
247 continue; 375 continue;
248 } 376 }
249 /* read nameservers to query */ 377 /* read nameservers to query */
250 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && 378 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
251 nserv < MAXNS) { 379 char *q;
252 struct in_addr a; 380 struct addrinfo hints, *res;
381 char pbuf[NI_MAXSERV];
253 382
254 cp = buf + sizeof("nameserver") - 1; 383 cp = buf + sizeof("nameserver") - 1;
255 while (*cp == ' ' || *cp == '\t') 384 while (*cp == ' ' || *cp == '\t')
256 cp++; 385 cp++;
257 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { 386 if ((*cp == '\0') || (*cp == '\n'))
258 _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in); 387 continue;
259 _res.nsaddr_list[nserv].sin_family = AF_INET; 388 for (q = cp; *q; q++) {
260 _res.nsaddr_list[nserv].sin_port = 389 if (isspace(*q)) {
261 htons(NAMESERVER_PORT); 390 *q = '\0';
262 _res.nsaddr_list[nserv].sin_addr = a; 391 break;
392 }
393 }
394
395 /* Handle addresses enclosed in [] */
396 *pbuf = '\0';
397 if (*cp == '[') {
398 cp++;
399 if ((q = strchr(cp, ']')) == NULL)
400 continue;
401 *q++ = '\0';
402 /* Extract port, if specified */
403 if (*q++ == ':') {
404 if (strlcpy(pbuf, q, sizeof(pbuf)) >= sizeof(pbuf))
405 continue;
406 }
407 }
408 if (*pbuf == '\0')
409 snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
410
411 memset(&hints, 0, sizeof(hints));
412 hints.ai_flags = AI_NUMERICHOST;
413 hints.ai_socktype = SOCK_DGRAM;
414 res = NULL;
415 if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
416 res->ai_next == NULL) {
417 if (res->ai_addrlen <= sizeof(_res_extp->nsaddr_list[nserv])) {
418 memcpy(&_res_extp->nsaddr_list[nserv], res->ai_addr,
419 res->ai_addrlen);
420 } else {
421 memset(&_res_extp->nsaddr_list[nserv], 0,
422 sizeof(_res_extp->nsaddr_list[nserv]));
423 }
424 if (res->ai_addrlen <= sizeof(_resp->nsaddr_list[nserv])) {
425 memcpy(&_resp->nsaddr_list[nserv], res->ai_addr,
426 res->ai_addrlen);
427 } else {
428 memset(&_resp->nsaddr_list[nserv], 0,
429 sizeof(_resp->nsaddr_list[nserv]));
430 }
263 nserv++; 431 nserv++;
264 } 432 }
433 if (res)
434 freeaddrinfo(res);
265 continue; 435 continue;
266 } 436 }
267 if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) { 437#ifdef RESOLVSORT
438 if (MATCH(buf, "sortlist")) {
268 struct in_addr a; 439 struct in_addr a;
440#ifdef INET6
441 struct in6_addr a6;
442 int m, i;
443 u_char *u;
444#endif /* INET6 */
269 445
270 cp = buf + sizeof("sortlist") - 1; 446 cp = buf + sizeof("sortlist") - 1;
271 while (*cp == ' ' || *cp == '\t') 447 while (nsort < MAXRESOLVSORT) {
272 cp++; 448 while (*cp == ' ' || *cp == '\t')
273 while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) { 449 cp++;
274 if (net = strchr(buf2, '/')) 450 if (*cp == '\0' || *cp == '\n' || *cp == ';')
275 *net = '\0'; 451 break;
276 if (inet_aton(buf2, &a)) { 452 net = cp;
277 _res.sort_list[nsort].addr = a; 453 while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
278 if (net && inet_aton(net+1, &a)) { 454 isascii(*cp) && !isspace(*cp))
279 _res.sort_list[nsort].mask = a.s_addr; 455 cp++;
456 n = *cp;
457 *cp = 0;
458 if (inet_aton(net, &a)) {
459 _resp->sort_list[nsort].addr = a;
460 if (ISSORTMASK(n)) {
461 *cp++ = n;
462 net = cp;
463 while (*cp && *cp != ';' &&
464 isascii(*cp) && !isspace(*cp))
465 cp++;
466 n = *cp;
467 *cp = 0;
468 if (inet_aton(net, &a)) {
469 _resp->sort_list[nsort].mask = a.s_addr;
470 } else {
471 _resp->sort_list[nsort].mask =
472 net_mask(_resp->sort_list[nsort].addr);
473 }
280 } else { 474 } else {
281 _res.sort_list[nsort].mask = 475 _resp->sort_list[nsort].mask =
282 net_mask(_res.sort_list[nsort].addr); 476 net_mask(_resp->sort_list[nsort].addr);
283 } 477 }
478#ifdef INET6
479 _res_extp->sort_list[nsort].af = AF_INET;
480 _res_extp->sort_list[nsort].addr.ina =
481 _resp->sort_list[nsort].addr;
482 _res_extp->sort_list[nsort].mask.ina.s_addr =
483 _resp->sort_list[nsort].mask;
484#endif /* INET6 */
284 nsort++; 485 nsort++;
285 } 486 }
286 if (net) 487#ifdef INET6
287 *net = '/'; 488 else if (inet_pton(AF_INET6, net, &a6) == 1) {
288 cp += strlen(buf2); 489 _res_extp->sort_list[nsort].af = AF_INET6;
289 while (*cp == ' ' || *cp == '\t') 490 _res_extp->sort_list[nsort].addr.in6a = a6;
290 cp++; 491 u = (u_char *)&_res_extp->sort_list[nsort].mask.in6a;
492 *cp++ = n;
493 net = cp;
494 while (*cp && *cp != ';' &&
495 isascii(*cp) && !isspace(*cp))
496 cp++;
497 m = n;
498 n = *cp;
499 *cp = 0;
500 switch (m) {
501 case '/':
502 m = atoi(net);
503 break;
504 case '&':
505 if (inet_pton(AF_INET6, net, u) == 1) {
506 m = -1;
507 break;
508 }
509 /* FALLTHROUGH */
510 default:
511 m = sizeof(struct in6_addr) * NBBY;
512 break;
513 }
514 if (m >= 0) {
515 for (i = 0; i < sizeof(struct in6_addr); i++) {
516 if (m <= 0) {
517 *u = 0;
518 } else {
519 m -= NBBY;
520 *u = (u_char)~0;
521 if (m < 0)
522 *u <<= -m;
523 }
524 u++;
525 }
526 }
527 nsort++;
528 }
529#endif /* INET6 */
530 *cp = n;
291 } 531 }
292 continue; 532 continue;
293 } 533 }
294 if (!strncmp(buf, "options", sizeof("options") -1)) { 534#endif
535 if (MATCH(buf, "options")) {
295 res_setoptions(buf + sizeof("options") - 1, "conf"); 536 res_setoptions(buf + sizeof("options") - 1, "conf");
296 continue; 537 continue;
297 } 538 }
298 } 539 }
299 if (nserv > 1) 540 if (nserv > 1)
300 _res.nscount = nserv; 541 _resp->nscount = nserv;
301 _res.nsort = nsort; 542#ifdef RESOLVSORT
543 _resp->nsort = nsort;
544#endif
302 (void) fclose(fp); 545 (void) fclose(fp);
303 } 546 }
304 if (_res.defdname[0] == 0) { 547 if (_resp->defdname[0] == 0 &&
305 if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 && 548 gethostname(buf, sizeof(_resp->defdname) - 1) == 0 &&
306 (cp = strchr(buf, '.'))) 549 (cp = strchr(buf, '.')) != NULL)
307 (void)strcpy(_res.defdname, cp + 1); 550 {
551 strlcpy(_resp->defdname, cp + 1,
552 sizeof(_resp->defdname));
308 } 553 }
309 554
310 /* find components of local domain that might be searched */ 555 /* find components of local domain that might be searched */
311 if (havesearch == 0) { 556 if (havesearch == 0) {
312 pp = _res.dnsrch; 557 pp = _resp->dnsrch;
313 *pp++ = _res.defdname; 558 *pp++ = _resp->defdname;
314#ifndef SEARCH_LOCAL_DOMAINS
315 *pp = NULL; 559 *pp = NULL;
316#else 560
317 for (cp = _res.defdname, n = 0; *cp; cp++) 561#ifndef RFC1535
318 if (*cp == '.') 562 dots = 0;
319 n++; 563 for (cp = _resp->defdname; *cp; cp++)
320 cp = _res.defdname; 564 dots += (*cp == '.');
321 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; 565
322 n--) { 566 cp = _resp->defdname;
323 cp = strchr(cp, '.'); 567 while (pp < _resp->dnsrch + MAXDFLSRCH) {
324 *pp++ = ++cp; 568 if (dots < LOCALDOMAINPARTS)
569 break;
570 cp = strchr(cp, '.') + 1; /* we know there is one */
571 *pp++ = cp;
572 dots--;
325 } 573 }
326 *pp++ = 0; 574 *pp = NULL;
327#endif 575#ifdef DEBUG
576 if (_resp->options & RES_DEBUG) {
577 printf(";; res_init()... default dnsrch list:\n");
578 for (pp = _resp->dnsrch; *pp; pp++)
579 printf(";;\t%s\n", *pp);
580 printf(";;\t..END..\n");
581 }
582#endif /* DEBUG */
583#endif /* !RFC1535 */
328 } 584 }
329 585
330 if ((cp = getenv("RES_OPTIONS")) != NULL) 586 if (issetugid())
587 _resp->options |= RES_NOALIASES;
588 else if ((cp = getenv("RES_OPTIONS")) != NULL)
331 res_setoptions(cp, "env"); 589 res_setoptions(cp, "env");
332 _res.options |= RES_INIT; 590 _resp->options |= RES_INIT;
333 return (0); 591 return (0);
334} 592}
335 593
594/* ARGSUSED */
336static void 595static void
337res_setoptions(options, source) 596res_setoptions(char *options, char *source)
338 char *options, *source;
339{ 597{
598 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
340 char *cp = options; 599 char *cp = options;
341 int i; 600 char *endp;
601 long l;
342 602
343#ifdef DEBUG 603#ifdef DEBUG
344 if (_res.options & RES_DEBUG) { 604 if (_resp->options & RES_DEBUG)
345 printf(";; res_setoptions(\"%s\", \"%s\")...\n", 605 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
346 options, source); 606 options, source);
347 }
348#endif 607#endif
349 while (*cp) { 608 while (*cp) {
350 /* skip leading and inner runs of spaces */ 609 /* skip leading and inner runs of spaces */
351 while (*cp == ' ' || *cp == '\t') 610 while (*cp == ' ' || *cp == '\t')
352 cp++; 611 cp++;
353 /* search for and process individual options */ 612 /* search for and process individual options */
354 if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) { 613 if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
355 i = atoi(cp + sizeof("ndots:") - 1); 614 char *p = cp + sizeof("ndots:") - 1;
356 if (i <= RES_MAXNDOTS) 615 l = strtol(p, &endp, 10);
357 _res.ndots = i; 616 if (l >= 0 && endp != p &&
358 else 617 (*endp = '\0' || isspace(*endp))) {
359 _res.ndots = RES_MAXNDOTS; 618 if (l <= RES_MAXNDOTS)
619 _resp->ndots = l;
620 else
621 _resp->ndots = RES_MAXNDOTS;
360#ifdef DEBUG 622#ifdef DEBUG
361 if (_res.options & RES_DEBUG) { 623 if (_resp->options & RES_DEBUG)
362 printf(";;\tndots=%d\n", _res.ndots); 624 printf(";;\tndots=%u\n", _resp->ndots);
363 }
364#endif 625#endif
365 } else if (!strncmp(cp, "debug", sizeof("debug")-1)) { 626 }
627 } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
366#ifdef DEBUG 628#ifdef DEBUG
367 if (!(_res.options & RES_DEBUG)) { 629 if (!(_resp->options & RES_DEBUG)) {
368 printf(";; res_setoptions(\"%s\", \"%s\")..\n", 630 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
369 options, source); 631 options, source);
370 _res.options |= RES_DEBUG; 632 _resp->options |= RES_DEBUG;
371 } 633 }
372 printf(";;\tdebug\n"); 634 printf(";;\tdebug\n");
373#endif 635#endif
636 } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
637 _resp->options |= RES_USE_INET6;
638 } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
639 _resp->options |= RES_INSECURE1;
640 } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
641 _resp->options |= RES_INSECURE2;
642 } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
643 _resp->options |= RES_USE_EDNS0;
644 } else if (!strncmp(cp, "tcp", sizeof("tcp") - 1)) {
645 _resp->options |= RES_USEVC;
374 } else { 646 } else {
375 /* XXX - print a warning here? */ 647 /* XXX - print a warning here? */
376 } 648 }
@@ -380,15 +652,17 @@ res_setoptions(options, source)
380 } 652 }
381} 653}
382 654
655#ifdef RESOLVSORT
656/* XXX - should really support CIDR which means explicit masks always. */
383static u_int32_t 657static u_int32_t
384net_mask(in) /* XXX - should really use system's version of this */ 658net_mask(struct in_addr in) /* XXX - should really use system's version of this */
385 struct in_addr in;
386{ 659{
387 register u_int32_t i = ntohl(in.s_addr); 660 u_int32_t i = ntohl(in.s_addr);
388 661
389 if (IN_CLASSA(i)) 662 if (IN_CLASSA(i))
390 return (htonl(IN_CLASSA_NET)); 663 return (htonl(IN_CLASSA_NET));
391 if (IN_CLASSB(i)) 664 else if (IN_CLASSB(i))
392 return (htonl(IN_CLASSB_NET)); 665 return (htonl(IN_CLASSB_NET));
393 return (htonl(IN_CLASSC_NET)); 666 return (htonl(IN_CLASSC_NET));
394} 667}
668#endif
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
index 25f025e147..5c6b273abe 100644
--- a/src/lib/libc/net/res_mkquery.c
+++ b/src/lib/libc/net/res_mkquery.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_mkquery.c,v 1.5 1995/02/25 06:20:58 cgd Exp $ */ 1/* $OpenBSD: res_mkquery.c,v 1.17 2005/08/06 20:30:04 espie 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,101 +51,109 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
56#if defined(LIBC_SCCS) && !defined(lint) 54#include <sys/types.h>
57#if 0
58static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_mkquery.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp ";
60#else
61static 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> 55#include <sys/param.h>
66#include <netinet/in.h> 56#include <netinet/in.h>
67#include <arpa/nameser.h> 57#include <arpa/nameser.h>
68#include <resolv.h> 58
69#include <stdio.h> 59#include <stdio.h>
60#include <netdb.h>
61#include <resolv.h>
70#include <string.h> 62#include <string.h>
71 63
64#include "thread_private.h"
65
72/* 66/*
73 * Form all types of queries. 67 * Form all types of queries.
74 * Returns the size of the result or -1. 68 * Returns the size of the result or -1.
75 */ 69 */
76res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) 70/* ARGSUSED */
77 int op; /* opcode of query */ 71int
78 const char *dname; /* domain name */ 72res_mkquery(int op,
79 int class, type; /* class and type of query */ 73 const char *dname, /* opcode of query */
80 const char *data; /* resource record data */ 74 int class, /* domain name */
81 int datalen; /* length of data */ 75 int type, /* class and type of query */
82 const char *newrr_in; /* new rr for modify or append */ 76 const u_char *data, /* resource record data */
83 char *buf; /* buffer to put query */ 77 int datalen, /* length of data */
84 int buflen; /* size of buffer */ 78 const u_char *newrr_in, /* new rr for modify or append */
79 u_char *buf, /* buffer to put query */
80 int buflen) /* size of buffer */
85{ 81{
86 register HEADER *hp; 82 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
87 register char *cp; 83 HEADER *hp;
88 register int n; 84 u_char *cp, *ep;
89 struct rrec *newrr = (struct rrec *) newrr_in; 85 int n;
90 char *dnptrs[10], **dpp, **lastdnptr; 86 u_char *dnptrs[20], **dpp, **lastdnptr;
91 87
88 if (_res_init(0) == -1) {
89 h_errno = NETDB_INTERNAL;
90 return (-1);
91 }
92#ifdef DEBUG 92#ifdef DEBUG
93 if (_res.options & RES_DEBUG) 93 if (_resp->options & RES_DEBUG)
94 printf(";; res_mkquery(%d, %s, %d, %d)\n", 94 printf(";; res_mkquery(%d, %s, %d, %d)\n",
95 op, dname, class, type); 95 op, dname, class, type);
96#endif 96#endif
97 /* 97 /*
98 * Initialize header fields. 98 * Initialize header fields.
99 *
100 * A special random number generator is used to create non predictable
101 * and non repeating ids over a long period. It also avoids reuse
102 * by switching between two distinct number cycles.
99 */ 103 */
100 if ((buf == NULL) || (buflen < sizeof(HEADER))) 104
101 return(-1); 105 if ((buf == NULL) || (buflen < HFIXEDSZ))
102 bzero(buf, sizeof(HEADER)); 106 return (-1);
107 bzero(buf, HFIXEDSZ);
103 hp = (HEADER *) buf; 108 hp = (HEADER *) buf;
104 hp->id = htons(++_res.id); 109 _resp->id = res_randomid();
110 hp->id = htons(_resp->id);
105 hp->opcode = op; 111 hp->opcode = op;
106 hp->pr = (_res.options & RES_PRIMARY) != 0; 112 hp->rd = (_resp->options & RES_RECURSE) != 0;
107 hp->rd = (_res.options & RES_RECURSE) != 0;
108 hp->rcode = NOERROR; 113 hp->rcode = NOERROR;
109 cp = buf + sizeof(HEADER); 114 cp = buf + HFIXEDSZ;
110 buflen -= sizeof(HEADER); 115 ep = buf + buflen;
111 dpp = dnptrs; 116 dpp = dnptrs;
112 *dpp++ = buf; 117 *dpp++ = buf;
113 *dpp++ = NULL; 118 *dpp++ = NULL;
114 lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 119 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
115 /* 120 /*
116 * perform opcode specific processing 121 * perform opcode specific processing
117 */ 122 */
118 switch (op) { 123 switch (op) {
119 case QUERY: 124 case QUERY: /*FALLTHROUGH*/
120 if ((buflen -= QFIXEDSZ) < 0) 125 case NS_NOTIFY_OP:
121 return(-1); 126 if (ep - cp < QFIXEDSZ)
122 if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen, 127 return (-1);
123 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) 128 if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
129 lastdnptr)) < 0)
124 return (-1); 130 return (-1);
125 cp += n; 131 cp += n;
126 buflen -= n; 132 __putshort(type, cp);
127 __putshort(type, (u_char *)cp); 133 cp += INT16SZ;
128 cp += sizeof(u_int16_t); 134 __putshort(class, cp);
129 __putshort(class, (u_char *)cp); 135 cp += INT16SZ;
130 cp += sizeof(u_int16_t);
131 hp->qdcount = htons(1); 136 hp->qdcount = htons(1);
132 if (op == QUERY || data == NULL) 137 if (op == QUERY || data == NULL)
133 break; 138 break;
134 /* 139 /*
135 * Make an additional record for completion domain. 140 * Make an additional record for completion domain.
136 */ 141 */
137 buflen -= RRFIXEDSZ; 142 if (ep - cp < RRFIXEDSZ)
138 if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen, 143 return (-1);
139 (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) 144 n = dn_comp((char *)data, cp, ep - cp - RRFIXEDSZ, dnptrs,
145 lastdnptr);
146 if (n < 0)
140 return (-1); 147 return (-1);
141 cp += n; 148 cp += n;
142 buflen -= n; 149 __putshort(T_NULL, cp);
143 __putshort(T_NULL, (u_char *)cp); 150 cp += INT16SZ;
144 cp += sizeof(u_int16_t); 151 __putshort(class, cp);
145 __putshort(class, (u_char *)cp); 152 cp += INT16SZ;
146 cp += sizeof(u_int16_t); 153 __putlong(0, cp);
147 __putlong(0, (u_char *)cp); 154 cp += INT32SZ;
148 cp += sizeof(u_int32_t); 155 __putshort(0, cp);
149 __putshort(0, (u_char *)cp); 156 cp += INT16SZ;
150 cp += sizeof(u_int16_t);
151 hp->arcount = htons(1); 157 hp->arcount = htons(1);
152 break; 158 break;
153 159
@@ -155,82 +161,72 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
155 /* 161 /*
156 * Initialize answer section 162 * Initialize answer section
157 */ 163 */
158 if (buflen < 1 + RRFIXEDSZ + datalen) 164 if (ep - cp < 1 + RRFIXEDSZ + datalen)
159 return (-1); 165 return (-1);
160 *cp++ = '\0'; /* no domain name */ 166 *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); 167 __putshort(type, cp);
196 cp += sizeof(u_int16_t); 168 cp += INT16SZ;
197 __putshort(class, cp); 169 __putshort(class, cp);
198 cp += sizeof(u_int16_t); 170 cp += INT16SZ;
199 __putlong(0, cp); 171 __putlong(0, cp);
200 cp += sizeof(u_int32_t); 172 cp += INT32SZ;
201 __putshort(datalen, cp); 173 __putshort(datalen, cp);
202 cp += sizeof(u_int16_t); 174 cp += INT16SZ;
203 if (datalen) { 175 if (datalen) {
204 bcopy(data, cp, datalen); 176 bcopy(data, cp, datalen);
205 cp += datalen; 177 cp += datalen;
206 } 178 }
207 if ( (op == UPDATED) || (op == UPDATEDA) ) { 179 hp->ancount = htons(1);
208 hp->ancount = htons(0);
209 break;
210 }
211 /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
212
213 case UPDATEA: /* Add new resource record */
214 buflen -= RRFIXEDSZ + datalen;
215 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
216 return (-1);
217 cp += n;
218 __putshort(newrr->r_type, cp);
219 cp += sizeof(u_int16_t);
220 __putshort(newrr->r_class, cp);
221 cp += sizeof(u_int16_t);
222 __putlong(0, cp);
223 cp += sizeof(u_int32_t);
224 __putshort(newrr->r_size, cp);
225 cp += sizeof(u_int16_t);
226 if (newrr->r_size) {
227 bcopy(newrr->r_data, cp, newrr->r_size);
228 cp += newrr->r_size;
229 }
230 hp->ancount = htons(0);
231 break; 180 break;
232 181
233#endif /* ALLOW_UPDATES */ 182 default:
183 return (-1);
234 } 184 }
235 return (cp - buf); 185 return (cp - buf);
236} 186}
187
188/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
189int
190res_opt(int n0,
191 u_char *buf, /* buffer to put query */
192 int buflen, /* size of buffer */
193 int anslen) /* answer buffer length */
194{
195 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
196 HEADER *hp;
197 u_char *cp, *ep;
198
199 hp = (HEADER *) buf;
200 cp = buf + n0;
201 ep = buf + buflen;
202
203 if (ep - cp < 1 + RRFIXEDSZ)
204 return -1;
205
206 *cp++ = 0; /* "." */
207
208 __putshort(T_OPT, cp); /* TYPE */
209 cp += INT16SZ;
210 if (anslen > 0xffff)
211 anslen = 0xffff; /* limit to 16bit value */
212 __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
213 cp += INT16SZ;
214 *cp++ = NOERROR; /* extended RCODE */
215 *cp++ = 0; /* EDNS version */
216 if (_resp->options & RES_USE_DNSSEC) {
217#ifdef DEBUG
218 if (_resp->options & RES_DEBUG)
219 printf(";; res_opt()... ENDS0 DNSSEC OK\n");
220#endif /* DEBUG */
221 __putshort(DNS_MESSAGEEXTFLAG_DO, cp); /* EDNS Z field */
222 cp += INT16SZ;
223 } else {
224 __putshort(0, cp); /* EDNS Z field */
225 cp += INT16SZ;
226 }
227 __putshort(0, cp); /* RDLEN */
228 cp += INT16SZ;
229 hp->arcount = htons(ntohs(hp->arcount) + 1);
230
231 return cp - buf;
232}
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
index 7649462e56..c8a45a5df5 100644
--- a/src/lib/libc/net/res_query.c
+++ b/src/lib/libc/net/res_query.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $ */ 1/* $OpenBSD: res_query.c,v 1.25 2007/05/16 04:14:23 ray Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1988, 1993
5 * -
4 * Copyright (c) 1988, 1993 6 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -53,26 +51,22 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
56#if defined(LIBC_SCCS) && !defined(lint) 54#include <sys/types.h>
57#if 0
58static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_query.c,v 1.1 1993/06/01 09:42:14 vixie Exp vixie ";
60#else
61static 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> 55#include <sys/param.h>
66#include <netinet/in.h> 56#include <netinet/in.h>
67#include <arpa/inet.h> 57#include <arpa/inet.h>
68#include <arpa/nameser.h> 58#include <arpa/nameser.h>
59
60#include <stdio.h>
69#include <netdb.h> 61#include <netdb.h>
70#include <resolv.h> 62#include <resolv.h>
71#include <stdio.h>
72#include <ctype.h> 63#include <ctype.h>
73#include <errno.h> 64#include <errno.h>
74#include <stdlib.h> 65#include <stdlib.h>
75#include <string.h> 66#include <string.h>
67#include <unistd.h>
68
69#include "thread_private.h"
76 70
77#if PACKETSZ > 1024 71#if PACKETSZ > 1024
78#define MAXPACKET PACKETSZ 72#define MAXPACKET PACKETSZ
@@ -80,8 +74,9 @@ static char rcsid[] = "$NetBSD: res_query.c,v 1.9 1995/02/25 06:58:58 cgd Exp $"
80#define MAXPACKET 1024 74#define MAXPACKET 1024
81#endif 75#endif
82 76
83char *__hostalias __P((const char *)); 77const char *hostalias(const char *);
84int h_errno; 78int h_errno;
79extern int res_opt(int, u_char *, int, int);
85 80
86/* 81/*
87 * Formulate a normal query, send, and await answer. 82 * Formulate a normal query, send, and await answer.
@@ -90,68 +85,79 @@ int h_errno;
90 * if no error is indicated and the answer count is nonzero. 85 * if no error is indicated and the answer count is nonzero.
91 * Return the size of the response on success, -1 on error. 86 * Return the size of the response on success, -1 on error.
92 * Error number is left in h_errno. 87 * Error number is left in h_errno.
88 *
93 * Caller must parse answer and determine whether it answers the question. 89 * Caller must parse answer and determine whether it answers the question.
94 */ 90 */
95res_query(name, class, type, answer, anslen) 91int
96 char *name; /* domain name */ 92res_query(const char *name,
97 int class, type; /* class and type of query */ 93 int class, /* domain name */
98 u_char *answer; /* buffer to put answer */ 94 int type, /* class and type of query */
99 int anslen; /* size of answer buffer */ 95 u_char *answer, /* buffer to put answer */
96 int anslen) /* size of answer buffer */
100{ 97{
101 char buf[MAXPACKET]; 98 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
102 HEADER *hp; 99 u_char buf[MAXPACKET];
100 HEADER *hp = (HEADER *) answer;
103 int n; 101 int n;
104 102
105 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 103 hp->rcode = NOERROR; /* default */
104
105 if (_res_init(0) == -1) {
106 h_errno = NETDB_INTERNAL;
106 return (-1); 107 return (-1);
108 }
107#ifdef DEBUG 109#ifdef DEBUG
108 if (_res.options & RES_DEBUG) 110 if (_resp->options & RES_DEBUG)
109 printf(";; res_query(%s, %d, %d)\n", name, class, type); 111 printf(";; res_query(%s, %d, %d)\n", name, class, type);
110#endif 112#endif
111 n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL, 113
112 buf, sizeof(buf)); 114 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
115 buf, sizeof(buf));
116 if (n > 0 && ((_resp->options & RES_USE_EDNS0) ||
117 (_resp->options & RES_USE_DNSSEC))) {
118 n = res_opt(n, buf, sizeof(buf), anslen);
119 }
113 120
114 if (n <= 0) { 121 if (n <= 0) {
115#ifdef DEBUG 122#ifdef DEBUG
116 if (_res.options & RES_DEBUG) 123 if (_resp->options & RES_DEBUG)
117 printf(";; res_query: mkquery failed\n"); 124 printf(";; res_query: mkquery failed\n");
118#endif 125#endif
119 h_errno = NO_RECOVERY; 126 h_errno = NO_RECOVERY;
120 return (n); 127 return (n);
121 } 128 }
122 n = res_send(buf, n, (char *)answer, anslen); 129 n = res_send(buf, n, answer, anslen);
123 if (n < 0) { 130 if (n < 0) {
124#ifdef DEBUG 131#ifdef DEBUG
125 if (_res.options & RES_DEBUG) 132 if (_resp->options & RES_DEBUG)
126 printf(";; res_query: send error\n"); 133 printf(";; res_query: send error\n");
127#endif 134#endif
128 h_errno = TRY_AGAIN; 135 h_errno = TRY_AGAIN;
129 return (n); 136 return (n);
130 } 137 }
131 138
132 hp = (HEADER *) answer;
133 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 139 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
134#ifdef DEBUG 140#ifdef DEBUG
135 if (_res.options & RES_DEBUG) 141 if (_resp->options & RES_DEBUG)
136 printf(";; rcode = %d, ancount=%d\n", hp->rcode, 142 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
137 ntohs(hp->ancount)); 143 ntohs(hp->ancount));
138#endif 144#endif
139 switch (hp->rcode) { 145 switch (hp->rcode) {
140 case NXDOMAIN: 146 case NXDOMAIN:
141 h_errno = HOST_NOT_FOUND; 147 h_errno = HOST_NOT_FOUND;
142 break; 148 break;
143 case SERVFAIL: 149 case SERVFAIL:
144 h_errno = TRY_AGAIN; 150 h_errno = TRY_AGAIN;
145 break; 151 break;
146 case NOERROR: 152 case NOERROR:
147 h_errno = NO_DATA; 153 h_errno = NO_DATA;
148 break; 154 break;
149 case FORMERR: 155 case FORMERR:
150 case NOTIMP: 156 case NOTIMP:
151 case REFUSED: 157 case REFUSED:
152 default: 158 default:
153 h_errno = NO_RECOVERY; 159 h_errno = NO_RECOVERY;
154 break; 160 break;
155 } 161 }
156 return (-1); 162 return (-1);
157 } 163 }
@@ -162,39 +168,39 @@ res_query(name, class, type, answer, anslen)
162 * Formulate a normal query, send, and retrieve answer in supplied buffer. 168 * Formulate a normal query, send, and retrieve answer in supplied buffer.
163 * Return the size of the response on success, -1 on error. 169 * Return the size of the response on success, -1 on error.
164 * If enabled, implement search rules until answer or unrecoverable failure 170 * If enabled, implement search rules until answer or unrecoverable failure
165 * is detected. Error number is left in h_errno. 171 * is detected. Error code, if any, is left in h_errno.
166 * Only useful for queries in the same name hierarchy as the local host
167 * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
168 */ 172 */
169int 173int
170res_search(name, class, type, answer, anslen) 174res_search(const char *name,
171 const char *name; /* domain name */ 175 int class, /* domain name */
172 int class, type; /* class and type of query */ 176 int type, /* class and type of query */
173 u_char *answer; /* buffer to put answer */ 177 u_char *answer, /* buffer to put answer */
174 int anslen; /* size of answer */ 178 int anslen) /* size of answer */
175{ 179{
176 register char *cp, **domain; 180 const char *cp, * const *domain;
177 int dots, trailing_dot, ret, got_nodata, saved_herrno, tried_as_is; 181 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
182 HEADER *hp = (HEADER *) answer;
183 u_int dots;
184 int trailing_dot, ret, saved_herrno;
185 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
178 186
179 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 187 if (_res_init(0) == -1) {
188 h_errno = NETDB_INTERNAL;
180 return (-1); 189 return (-1);
181 190 }
182 got_nodata = 0;
183 errno = 0; 191 errno = 0;
184 h_errno = HOST_NOT_FOUND; /* default, if we never query */ 192 h_errno = HOST_NOT_FOUND; /* default, if we never query */
185 dots = 0; 193 dots = 0;
186 for (cp = (char *)name; *cp; cp++) { 194 for (cp = name; *cp; cp++)
187 if (*cp == '.') 195 dots += (*cp == '.');
188 dots++;
189 }
190 trailing_dot = 0; 196 trailing_dot = 0;
191 if ((cp > name) && (*--cp == '.')) 197 if (cp > name && *--cp == '.')
192 trailing_dot++; 198 trailing_dot++;
193 199
194 /* 200 /*
195 * if there aren't any dots, it could be a user-level alias 201 * if there aren't any dots, it could be a user-level alias
196 */ 202 */
197 if (!dots && (cp = __hostalias(name))) 203 if (!dots && (cp = __hostalias(name)) != NULL)
198 return (res_query(cp, class, type, answer, anslen)); 204 return (res_query(cp, class, type, answer, anslen));
199 205
200 /* 206 /*
@@ -202,8 +208,7 @@ res_search(name, class, type, answer, anslen)
202 * 'as is'. The threshold can be set with the "ndots" option. 208 * 'as is'. The threshold can be set with the "ndots" option.
203 */ 209 */
204 saved_herrno = -1; 210 saved_herrno = -1;
205 tried_as_is = 0; 211 if (dots >= _resp->ndots) {
206 if (dots >= _res.ndots) {
207 ret = res_querydomain(name, NULL, class, type, answer, anslen); 212 ret = res_querydomain(name, NULL, class, type, answer, anslen);
208 if (ret > 0) 213 if (ret > 0)
209 return (ret); 214 return (ret);
@@ -217,15 +222,19 @@ res_search(name, class, type, answer, anslen)
217 * - there is at least one dot, there is no trailing dot, 222 * - there is at least one dot, there is no trailing dot,
218 * and RES_DNSRCH is set. 223 * and RES_DNSRCH is set.
219 */ 224 */
220 if ((!dots && (_res.options & RES_DEFNAMES)) || 225 if ((!dots && (_resp->options & RES_DEFNAMES)) ||
221 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { 226 (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
222 for (domain = _res.dnsrch; *domain; domain++) { 227 int done = 0;
223 int done = 0; 228
229 for (domain = (const char * const *)_resp->dnsrch;
230 *domain && !done;
231 domain++) {
224 232
225 ret = res_querydomain(name, *domain, class, type, 233 ret = res_querydomain(name, *domain, class, type,
226 answer, anslen); 234 answer, anslen);
227 if (ret > 0) 235 if (ret > 0)
228 return (ret); 236 return (ret);
237
229 /* 238 /*
230 * If no server present, give up. 239 * If no server present, give up.
231 * If name isn't found in this domain, 240 * If name isn't found in this domain,
@@ -251,24 +260,27 @@ res_search(name, class, type, answer, anslen)
251 case HOST_NOT_FOUND: 260 case HOST_NOT_FOUND:
252 /* keep trying */ 261 /* keep trying */
253 break; 262 break;
263 case TRY_AGAIN:
264 if (hp->rcode == SERVFAIL) {
265 /* try next search element, if any */
266 got_servfail++;
267 break;
268 }
269 /* FALLTHROUGH */
254 default: 270 default:
255 /* anything else implies that we're done */ 271 /* anything else implies that we're done */
256 done++; 272 done++;
257 } 273 }
258 /* 274
259 * if we got here for some reason other than DNSRCH, 275 /* if we got here for some reason other than DNSRCH,
260 * we only wanted one iteration of the loop, so stop. 276 * we only wanted one iteration of the loop, so stop.
261 */ 277 */
262 if (!(_res.options & RES_DNSRCH)) 278 if (!(_resp->options & RES_DNSRCH))
263 done++; 279 done++;
264
265 if (done)
266 break;
267 } 280 }
268 } 281 }
269 282
270 /* 283 /* if we have not already tried the name "as is", do that now.
271 * if we have not already tried the name "as is", do that now.
272 * note that we do this regardless of how many dots were in the 284 * note that we do this regardless of how many dots were in the
273 * name or whether it ends with a dot. 285 * name or whether it ends with a dot.
274 */ 286 */
@@ -276,11 +288,9 @@ res_search(name, class, type, answer, anslen)
276 ret = res_querydomain(name, NULL, class, type, answer, anslen); 288 ret = res_querydomain(name, NULL, class, type, answer, anslen);
277 if (ret > 0) 289 if (ret > 0)
278 return (ret); 290 return (ret);
279 saved_herrno = h_errno;
280 } 291 }
281 292
282 /* 293 /* if we got here, we didn't satisfy the search.
283 * if we got here, we didn't satisfy the search.
284 * if we did an initial full query, return that query's h_errno 294 * 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). 295 * (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. 296 * else if we ever got a nodata, send that back as the reason.
@@ -291,6 +301,8 @@ res_search(name, class, type, answer, anslen)
291 h_errno = saved_herrno; 301 h_errno = saved_herrno;
292 else if (got_nodata) 302 else if (got_nodata)
293 h_errno = NO_DATA; 303 h_errno = NO_DATA;
304 else if (got_servfail)
305 h_errno = TRY_AGAIN;
294 return (-1); 306 return (-1);
295} 307}
296 308
@@ -298,20 +310,29 @@ res_search(name, class, type, answer, anslen)
298 * Perform a call on res_query on the concatenation of name and domain, 310 * Perform a call on res_query on the concatenation of name and domain,
299 * removing a trailing dot from name if domain is NULL. 311 * removing a trailing dot from name if domain is NULL.
300 */ 312 */
301res_querydomain(name, domain, class, type, answer, anslen) 313int
302 char *name, *domain; 314res_querydomain(const char *name,
303 int class, type; /* class and type of query */ 315 const char *domain,
304 u_char *answer; /* buffer to put answer */ 316 int class, /* class and type of query */
305 int anslen; /* size of answer */ 317 int type,
318 u_char *answer, /* buffer to put answer */
319 int anslen) /* size of answer */
306{ 320{
307 char nbuf[2*MAXDNAME+2]; 321#ifdef DEBUG
308 char *longname = nbuf; 322 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
323#endif
324 char nbuf[MAXDNAME*2+1+1];
325 const char *longname = nbuf;
309 int n; 326 int n;
310 327
328 if (_res_init(0) == -1) {
329 h_errno = NETDB_INTERNAL;
330 return (-1);
331 }
311#ifdef DEBUG 332#ifdef DEBUG
312 if (_res.options & RES_DEBUG) 333 if (_resp->options & RES_DEBUG)
313 printf(";; res_querydomain(%s, %s, %d, %d)\n", 334 printf(";; res_querydomain(%s, %s, %d, %d)\n",
314 name, domain, class, type); 335 name, domain?domain:"<Nil>", class, type);
315#endif 336#endif
316 if (domain == NULL) { 337 if (domain == NULL) {
317 /* 338 /*
@@ -325,38 +346,51 @@ res_querydomain(name, domain, class, type, answer, anslen)
325 } else 346 } else
326 longname = name; 347 longname = name;
327 } else 348 } else
328 (void)sprintf(nbuf, "%.*s.%.*s", 349 snprintf(nbuf, sizeof nbuf, "%.*s.%.*s",
329 MAXDNAME, name, MAXDNAME, domain); 350 MAXDNAME, name, MAXDNAME, domain);
330 351
331 return (res_query(longname, class, type, answer, anslen)); 352 return (res_query(longname, class, type, answer, anslen));
332} 353}
333 354
334char * 355const char *
335__hostalias(name) 356hostalias(const char *name)
336 register const char *name;
337{ 357{
338 register char *cp1, *cp2; 358 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
359 char *cp1, *cp2;
339 FILE *fp; 360 FILE *fp;
340 char *file, *getenv(), *strcpy(), *strncpy(); 361 char *file;
341 char buf[BUFSIZ]; 362 char buf[BUFSIZ];
342 static char abuf[MAXDNAME]; 363 static char abuf[MAXDNAME];
364 size_t len;
343 365
366 if (_resp->options & RES_NOALIASES)
367 return (NULL);
344 file = getenv("HOSTALIASES"); 368 file = getenv("HOSTALIASES");
345 if (file == NULL || (fp = fopen(file, "r")) == NULL) 369 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
346 return (NULL); 370 return (NULL);
347 buf[sizeof(buf) - 1] = '\0'; 371 setbuf(fp, NULL);
348 while (fgets(buf, sizeof(buf), fp)) { 372 while ((cp1 = fgetln(fp, &len)) != NULL) {
349 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1); 373 if (cp1[len-1] == '\n')
374 len--;
375 if (len >= sizeof(buf) || len == 0)
376 continue;
377 (void)memcpy(buf, cp1, len);
378 buf[len] = '\0';
379
380 for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
381 ;
350 if (!*cp1) 382 if (!*cp1)
351 break; 383 break;
352 *cp1 = '\0'; 384 *cp1 = '\0';
353 if (!strcasecmp(buf, name)) { 385 if (!strcasecmp(buf, name)) {
354 while (isspace(*++cp1)); 386 while (isspace(*++cp1))
387 ;
355 if (!*cp1) 388 if (!*cp1)
356 break; 389 break;
357 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2); 390 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
358 abuf[sizeof(abuf) - 1] = *cp2 = '\0'; 391 ;
359 (void)strncpy(abuf, cp1, sizeof(abuf) - 1); 392 *cp2 = '\0';
393 strlcpy(abuf, cp1, sizeof(abuf));
360 fclose(fp); 394 fclose(fp);
361 return (abuf); 395 return (abuf);
362 } 396 }
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c
new file mode 100644
index 0000000000..f0beb7a573
--- /dev/null
+++ b/src/lib/libc/net/res_random.c
@@ -0,0 +1,264 @@
1/* $OpenBSD: res_random.c,v 1.17 2008/04/13 00:28:35 djm 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#define RU_OUT 180 /* Time after wich will be reseeded */
72#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
73#define RU_GEN 2 /* Starting generator */
74#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
75#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
76#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
77#define RU_ROUNDS 11 /* Number of rounds for permute (odd) */
78
79struct prf_ctx {
80 /* PRF lookup table for odd rounds (7 bits input to 8 bits output) */
81 u_char prf7[(RU_ROUNDS / 2) * (1 << 7)];
82
83 /* PRF lookup table for even rounds (8 bits input to 7 bits output) */
84 u_char prf8[((RU_ROUNDS + 1) / 2) * (1 << 8)];
85};
86
87#define PFAC_N 3
88const static u_int16_t pfacts[PFAC_N] = {
89 2,
90 3,
91 2729
92};
93
94static u_int16_t ru_x;
95static u_int16_t ru_seed, ru_seed2;
96static u_int16_t ru_a, ru_b;
97static u_int16_t ru_g;
98static u_int16_t ru_counter = 0;
99static u_int16_t ru_msb = 0;
100static struct prf_ctx *ru_prf = NULL;
101static long ru_reseed;
102
103static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
104static void res_initid(void);
105
106/*
107 * Do a fast modular exponation, returned value will be in the range
108 * of 0 - (mod-1)
109 */
110static u_int16_t
111pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
112{
113 u_int16_t s, t, u;
114
115 s = 1;
116 t = gen;
117 u = exp;
118
119 while (u) {
120 if (u & 1)
121 s = (s * t) % mod;
122 u >>= 1;
123 t = (t * t) % mod;
124 }
125 return (s);
126}
127
128/*
129 * 15-bit permutation based on Luby-Rackoff block cipher
130 */
131u_int
132permute15(u_int in)
133{
134 int i;
135 u_int left, right, tmp;
136
137 if (ru_prf == NULL)
138 return in;
139
140 left = (in >> 8) & 0x7f;
141 right = in & 0xff;
142
143 /*
144 * Each round swaps the width of left and right. Even rounds have
145 * a 7-bit left, odd rounds have an 8-bit left. Since this uses an
146 * odd number of rounds, left is always 8 bits wide at the end.
147 */
148 for (i = 0; i < RU_ROUNDS; i++) {
149 if ((i & 1) == 0)
150 tmp = ru_prf->prf8[(i << (8 - 1)) | right] & 0x7f;
151 else
152 tmp = ru_prf->prf7[((i - 1) << (7 - 1)) | right];
153 tmp ^= left;
154 left = right;
155 right = tmp;
156 }
157
158 return (right << 8) | left;
159}
160
161/*
162 * Initializes the seed and chooses a suitable generator. Also toggles
163 * the msb flag. The msb flag is used to generate two distinct
164 * cycles of random numbers and thus avoiding reuse of ids.
165 *
166 * This function is called from res_randomid() when needed, an
167 * application does not have to worry about it.
168 */
169static void
170res_initid(void)
171{
172 u_int16_t j, i;
173 u_int32_t tmp;
174 int noprime = 1;
175 struct timeval tv;
176
177 ru_x = arc4random_uniform(RU_M);
178
179 /* 15 bits of random seed */
180 tmp = arc4random();
181 ru_seed = (tmp >> 16) & 0x7FFF;
182 ru_seed2 = tmp & 0x7FFF;
183
184 /* Determine the LCG we use */
185 tmp = arc4random();
186 ru_b = (tmp & 0xfffe) | 1;
187 ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
188 while (ru_b % 3 == 0)
189 ru_b += 2;
190
191 j = arc4random_uniform(RU_N);
192
193 /*
194 * Do a fast gcd(j,RU_N-1), so we can find a j with
195 * gcd(j, RU_N-1) == 1, giving a new generator for
196 * RU_GEN^j mod RU_N
197 */
198
199 while (noprime) {
200 for (i = 0; i < PFAC_N; i++)
201 if (j % pfacts[i] == 0)
202 break;
203
204 if (i >= PFAC_N)
205 noprime = 0;
206 else
207 j = (j + 1) % RU_N;
208 }
209
210 ru_g = pmod(RU_GEN, j, RU_N);
211 ru_counter = 0;
212
213 /* Initialise PRF for Luby-Rackoff permutation */
214 if (ru_prf == NULL)
215 ru_prf = malloc(sizeof(*ru_prf));
216 if (ru_prf != NULL)
217 arc4random_buf(ru_prf, sizeof(*ru_prf));
218
219 gettimeofday(&tv, NULL);
220 ru_reseed = tv.tv_sec + RU_OUT;
221 ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
222}
223
224u_int
225res_randomid(void)
226{
227 struct timeval tv;
228
229 gettimeofday(&tv, NULL);
230 if (ru_counter >= RU_MAX || tv.tv_sec > ru_reseed)
231 res_initid();
232
233 /* Linear Congruential Generator */
234 ru_x = (ru_a * ru_x + ru_b) % RU_M;
235 ru_counter++;
236
237 return permute15(ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb;
238}
239
240#if 0
241int
242main(int argc, char **argv)
243{
244 int i, n;
245 u_int16_t wert;
246
247 res_initid();
248
249 printf("Generator: %u\n", ru_g);
250 printf("Seed: %u\n", ru_seed);
251 printf("Reseed at %ld\n", ru_reseed);
252 printf("Ru_X: %u\n", ru_x);
253 printf("Ru_A: %u\n", ru_a);
254 printf("Ru_B: %u\n", ru_b);
255
256 n = argc > 1 ? atoi(argv[1]) : 60001;
257 for (i=0;i<n;i++) {
258 wert = res_randomid();
259 printf("%u\n", wert);
260 }
261 return 0;
262}
263#endif
264
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index e608358180..09b1385892 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $ */ 1/* $OpenBSD: res_send.c,v 1.21 2008/05/11 05:03:03 brad Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
4 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -12,14 +14,10 @@
12 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 17 * 3. Neither the name of the University nor the names of its contributors
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software 18 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission. 19 * without specific prior written permission.
22 * 20 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -53,19 +51,22 @@
53 * --Copyright-- 51 * --Copyright--
54 */ 52 */
55 53
56#if defined(LIBC_SCCS) && !defined(lint) 54#ifndef INET6
57#if 0 55#define INET6
58static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
59static char rcsid[] = "$Id: res_send.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";
60#else
61static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
62#endif 56#endif
63#endif /* LIBC_SCCS and not lint */ 57
58 /* change this to "0"
59 * if you talk to a lot
60 * of multi-homed SunOS
61 * ("broken") name servers.
62 */
63#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
64 64
65/* 65/*
66 * Send query to name server and wait for reply. 66 * Send query to name server and wait for reply.
67 */ 67 */
68 68
69#include <sys/types.h>
69#include <sys/param.h> 70#include <sys/param.h>
70#include <sys/time.h> 71#include <sys/time.h>
71#include <sys/socket.h> 72#include <sys/socket.h>
@@ -73,139 +74,401 @@ static char rcsid[] = "$NetBSD: res_send.c,v 1.4 1995/02/25 06:21:01 cgd Exp $";
73#include <netinet/in.h> 74#include <netinet/in.h>
74#include <arpa/nameser.h> 75#include <arpa/nameser.h>
75#include <arpa/inet.h> 76#include <arpa/inet.h>
76#include <stdio.h> 77
77#include <errno.h> 78#include <errno.h>
79#include <netdb.h>
80#include <poll.h>
78#include <resolv.h> 81#include <resolv.h>
79#include <unistd.h> 82#include <stdio.h>
83#include <stdlib.h>
80#include <string.h> 84#include <string.h>
85#include <unistd.h>
86
87#include "thread_private.h"
81 88
82static int s = -1; /* socket used for communications */ 89static int s = -1; /* socket used for communications */
83static struct sockaddr no_addr; 90static int connected = 0; /* is the socket connected */
84 91static int vc = 0; /* is the socket a virtual ciruit? */
85#ifndef FD_SET 92static int af = 0; /* address family of socket */
86#define NFDBITS 32 93
87#define FD_SETSIZE 32 94#define CAN_RECONNECT 1
88#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) 95
89#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) 96#ifndef DEBUG
90#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) 97# define Dprint(cond, args) /*empty*/
91#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) 98# define DprintQ(cond, args, query, size) /*empty*/
99# define Aerror(file, string, error, address) /*empty*/
100# define Perror(file, string, error) /*empty*/
101#else
102# define Dprint(cond, args) if (cond) {fprintf args;} else {}
103# define DprintQ(cond, args, query, size) if (cond) {\
104 fprintf args;\
105 __fp_nquery(query, size, stdout);\
106 } else {}
107static char abuf[NI_MAXHOST];
108static char pbuf[NI_MAXSERV];
109static void Aerror(FILE *, char *, int, struct sockaddr *);
110static void Perror(FILE *, char *, int);
111
112 static void
113 Aerror(FILE *file, char *string, int error, struct sockaddr *address)
114 {
115 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
116 int save = errno;
117
118 if (_resp->options & RES_DEBUG) {
119 if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
120 pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
121 strlcpy(abuf, "?", sizeof(abuf));
122 strlcpy(pbuf, "?", sizeof(pbuf));
123 }
124 fprintf(file, "res_send: %s ([%s].%s): %s\n",
125 string, abuf, pbuf, strerror(error));
126 }
127 errno = save;
128 }
129 static void
130 Perror(FILE *file, char *string, int error)
131 {
132 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
133 int save = errno;
134
135 if (_resp->options & RES_DEBUG) {
136 fprintf(file, "res_send: %s: %s\n",
137 string, strerror(error));
138 }
139 errno = save;
140 }
92#endif 141#endif
93 142
94res_send(buf, buflen, answer, anslen) 143static res_send_qhook Qhook = NULL;
95 const char *buf; 144static res_send_rhook Rhook = NULL;
96 int buflen; 145
97 char *answer; 146void
98 int anslen; 147res_send_setqhook(res_send_qhook hook)
99{ 148{
100 register int n; 149
101 int try, v_circuit, resplen, ns; 150 Qhook = hook;
102 int gotsomewhere = 0, connected = 0; 151}
103 int connreset = 0; 152
104 u_short id, len; 153void
105 char *cp; 154res_send_setrhook(res_send_rhook hook)
106 fd_set dsmask; 155{
107 struct timeval timeout; 156
108 HEADER *hp = (HEADER *) buf; 157 Rhook = hook;
109 HEADER *anhp = (HEADER *) answer; 158}
110 u_int badns; /* XXX NSMAX can't exceed #/bits per this */ 159
111 struct iovec iov[2]; 160#ifdef INET6
112 int terrno = ETIMEDOUT; 161static struct sockaddr * get_nsaddr(size_t);
113 char junk[512]; 162
114 163/*
115#ifdef DEBUG 164 * pick appropriate nsaddr_list for use. see res_init() for initialization.
116 if ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY)) { 165 */
117 printf(";; res_send()\n"); 166static struct sockaddr *
118 __p_query(buf); 167get_nsaddr(size_t n)
168{
169 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
170 struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
171 &_res_ext);
172
173 if (!_resp->nsaddr_list[n].sin_family) {
174 /*
175 * - _res_extp->nsaddr_list[n] holds an address that is larger
176 * than struct sockaddr, and
177 * - user code did not update _resp->nsaddr_list[n].
178 */
179 return (struct sockaddr *)&_res_extp->nsaddr_list[n];
180 } else {
181 /*
182 * - user code updated _res.nsaddr_list[n], or
183 * - _resp->nsaddr_list[n] has the same content as
184 * _res_extp->nsaddr_list[n].
185 */
186 return (struct sockaddr *)&_resp->nsaddr_list[n];
119 } 187 }
188}
189#else
190#define get_nsaddr(n) ((struct sockaddr *)&_resp->nsaddr_list[(n)])
191#endif
192
193/* int
194 * res_isourserver(ina)
195 * looks up "ina" in _resp->ns_addr_list[]
196 * returns:
197 * 0 : not found
198 * >0 : found
199 * author:
200 * paul vixie, 29may94
201 */
202int
203res_isourserver(const struct sockaddr_in *inp)
204{
205 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
206#ifdef INET6
207 const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
208 const struct sockaddr_in6 *srv6;
120#endif 209#endif
121 if (!(_res.options & RES_INIT)) 210 const struct sockaddr_in *srv;
122 if (res_init() == -1) { 211 int ns, ret;
123 return(-1); 212
213 ret = 0;
214 switch (inp->sin_family) {
215#ifdef INET6
216 case AF_INET6:
217 for (ns = 0; ns < _resp->nscount; ns++) {
218 srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
219 if (srv6->sin6_family == in6p->sin6_family &&
220 srv6->sin6_port == in6p->sin6_port &&
221 srv6->sin6_scope_id == in6p->sin6_scope_id &&
222 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
223 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
224 &in6p->sin6_addr))) {
225 ret++;
226 break;
227 }
124 } 228 }
125 v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; 229 break;
126 id = hp->id; 230#endif
231 case AF_INET:
232 for (ns = 0; ns < _resp->nscount; ns++) {
233 srv = (struct sockaddr_in *)get_nsaddr(ns);
234 if (srv->sin_family == inp->sin_family &&
235 srv->sin_port == inp->sin_port &&
236 (srv->sin_addr.s_addr == INADDR_ANY ||
237 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
238 ret++;
239 break;
240 }
241 }
242 break;
243 }
244 return (ret);
245}
246
247/* int
248 * res_nameinquery(name, type, class, buf, eom)
249 * look for (name,type,class) in the query section of packet (buf,eom)
250 * returns:
251 * -1 : format error
252 * 0 : not found
253 * >0 : found
254 * author:
255 * paul vixie, 29may94
256 */
257int
258res_nameinquery(const char *name, int type, int class, const u_char *buf,
259 const u_char *eom)
260{
261 const u_char *cp = buf + HFIXEDSZ;
262 int qdcount = ntohs(((HEADER*)buf)->qdcount);
263
264 while (qdcount-- > 0) {
265 char tname[MAXDNAME+1];
266 int n, ttype, tclass;
267
268 n = dn_expand(buf, eom, cp, tname, sizeof tname);
269 if (n < 0)
270 return (-1);
271 cp += n;
272 ttype = _getshort(cp); cp += INT16SZ;
273 tclass = _getshort(cp); cp += INT16SZ;
274 if (ttype == type &&
275 tclass == class &&
276 strcasecmp(tname, name) == 0)
277 return (1);
278 }
279 return (0);
280}
281
282/* int
283 * res_queriesmatch(buf1, eom1, buf2, eom2)
284 * is there a 1:1 mapping of (name,type,class)
285 * in (buf1,eom1) and (buf2,eom2)?
286 * returns:
287 * -1 : format error
288 * 0 : not a 1:1 mapping
289 * >0 : is a 1:1 mapping
290 * author:
291 * paul vixie, 29may94
292 */
293int
294res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2,
295 const u_char *eom2)
296{
297 const u_char *cp = buf1 + HFIXEDSZ;
298 int qdcount = ntohs(((HEADER*)buf1)->qdcount);
299
300 if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
301 return (0);
302 while (qdcount-- > 0) {
303 char tname[MAXDNAME+1];
304 int n, ttype, tclass;
305
306 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
307 if (n < 0)
308 return (-1);
309 cp += n;
310 ttype = _getshort(cp); cp += INT16SZ;
311 tclass = _getshort(cp); cp += INT16SZ;
312 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
313 return (0);
314 }
315 return (1);
316}
317
318int
319res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
320{
321 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
322 HEADER *hp = (HEADER *) buf;
323 HEADER *anhp = (HEADER *) ans;
324 int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
325 int n;
326 u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
327
328 if (_res_init(0) == -1) {
329 /* errno should have been set by res_init() in this case. */
330 return (-1);
331 }
332 DprintQ((_resp->options & RES_DEBUG) || (_resp->pfcode & RES_PRF_QUERY),
333 (stdout, ";; res_send()\n"), buf, buflen);
334 v_circuit = (_resp->options & RES_USEVC) || buflen > PACKETSZ;
335 gotsomewhere = 0;
336 connreset = 0;
337 terrno = ETIMEDOUT;
127 badns = 0; 338 badns = 0;
339
128 /* 340 /*
129 * Send request, RETRY times, or until successful 341 * Send request, RETRY times, or until successful
130 */ 342 */
131 for (try = 0; try < _res.retry; try++) { 343 for (try = 0; try < _resp->retry; try++) {
132 for (ns = 0; ns < _res.nscount; ns++) { 344 for (ns = 0; ns < _resp->nscount; ns++) {
133 if (badns & (1<<ns)) 345 struct sockaddr *nsap = get_nsaddr(ns);
134 continue; 346 socklen_t salen;
135#ifdef DEBUG 347
136 if (_res.options & RES_DEBUG) 348 if (nsap->sa_len)
137 printf(";; Querying server (# %d) address = %s\n", 349 salen = nsap->sa_len;
138 ns+1, 350#ifdef INET6
139 inet_ntoa(_res.nsaddr_list[ns].sin_addr)); 351 else if (nsap->sa_family == AF_INET6)
352 salen = sizeof(struct sockaddr_in6);
140#endif 353#endif
141 usevc: 354 else if (nsap->sa_family == AF_INET)
355 salen = sizeof(struct sockaddr_in);
356 else
357 salen = 0; /*unknown, die on connect*/
358
359 same_ns:
360 if (badns & (1 << ns)) {
361 res_close();
362 goto next_ns;
363 }
364
365 if (Qhook) {
366 int done = 0, loops = 0;
367
368 do {
369 res_sendhookact act;
370
371 act = (*Qhook)((struct sockaddr_in **)&nsap,
372 &buf, &buflen,
373 ans, anssiz, &resplen);
374 switch (act) {
375 case res_goahead:
376 done = 1;
377 break;
378 case res_nextns:
379 res_close();
380 goto next_ns;
381 case res_done:
382 return (resplen);
383 case res_modified:
384 /* give the hook another try */
385 if (++loops < 42) /*doug adams*/
386 break;
387 /*FALLTHROUGH*/
388 case res_error:
389 /*FALLTHROUGH*/
390 default:
391 return (-1);
392 }
393 } while (!done);
394 }
395
396 Dprint((_resp->options & RES_DEBUG) &&
397 getnameinfo(nsap, salen, abuf, sizeof(abuf),
398 NULL, 0, NI_NUMERICHOST) == 0,
399 (stdout, ";; Querying server (# %d) address = %s\n",
400 ns + 1, abuf));
401
142 if (v_circuit) { 402 if (v_circuit) {
143 int truncated = 0; 403 int truncated;
404 struct iovec iov[2];
405 u_short len;
406 u_char *cp;
144 407
145 /* 408 /*
146 * Use virtual circuit; 409 * Use virtual circuit;
147 * at most one attempt per server. 410 * at most one attempt per server.
148 */ 411 */
149 try = _res.retry; 412 try = _resp->retry;
150 if (s < 0) { 413 truncated = 0;
151 s = socket(AF_INET, SOCK_STREAM, 0); 414 if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
415 if (s >= 0)
416 res_close();
417
418 af = nsap->sa_family;
419 s = socket(af, SOCK_STREAM, 0);
152 if (s < 0) { 420 if (s < 0) {
153 terrno = errno; 421 terrno = errno;
154#ifdef DEBUG 422 Perror(stderr, "socket(vc)", errno);
155 if (_res.options & RES_DEBUG) 423#if 0
156 perror("socket (vc) failed"); 424 return (-1);
425#else
426 badns |= (1 << ns);
427 res_close();
428 goto next_ns;
157#endif 429#endif
158 continue;
159 } 430 }
160 if (connect(s, 431 errno = 0;
161 (struct sockaddr *)&(_res.nsaddr_list[ns]), 432 if (connect(s, nsap, salen) < 0) {
162 sizeof(struct sockaddr)) < 0) {
163 terrno = errno; 433 terrno = errno;
164#ifdef DEBUG 434 Aerror(stderr, "connect/vc",
165 if (_res.options & RES_DEBUG) 435 errno, nsap);
166 perror("connect failed"); 436 badns |= (1 << ns);
167#endif 437 res_close();
168 (void) close(s); 438 goto next_ns;
169 s = -1;
170 continue;
171 } 439 }
440 vc = 1;
172 } 441 }
173 /* 442 /*
174 * Send length & message 443 * Send length & message
175 */ 444 */
176 len = htons((u_short)buflen); 445 putshort((u_short)buflen, (u_char*)&len);
177 iov[0].iov_base = (caddr_t)&len; 446 iov[0].iov_base = (caddr_t)&len;
178 iov[0].iov_len = sizeof(len); 447 iov[0].iov_len = INT16SZ;
179 iov[1].iov_base = (char *)buf; 448 iov[1].iov_base = (caddr_t)buf;
180 iov[1].iov_len = buflen; 449 iov[1].iov_len = buflen;
181 if (writev(s, iov, 2) != sizeof(len) + buflen) { 450 if (writev(s, iov, 2) != (INT16SZ + buflen)) {
182 terrno = errno; 451 terrno = errno;
183#ifdef DEBUG 452 Perror(stderr, "write failed", errno);
184 if (_res.options & RES_DEBUG) 453 badns |= (1 << ns);
185 perror("write failed"); 454 res_close();
186#endif 455 goto next_ns;
187 (void) close(s);
188 s = -1;
189 continue;
190 } 456 }
191 /* 457 /*
192 * Receive length & response 458 * Receive length & response
193 */ 459 */
194 cp = answer; 460 read_len:
195 len = sizeof(short); 461 cp = ans;
196 while (len != 0 && 462 len = INT16SZ;
197 (n = read(s, (char *)cp, (int)len)) > 0) { 463 while ((n = read(s, (char *)cp, (int)len)) > 0) {
198 cp += n; 464 cp += n;
199 len -= n; 465 if ((len -= n) <= 0)
466 break;
200 } 467 }
201 if (n <= 0) { 468 if (n <= 0) {
202 terrno = errno; 469 terrno = errno;
203#ifdef DEBUG 470 Perror(stderr, "read failed", errno);
204 if (_res.options & RES_DEBUG) 471 res_close();
205 perror("read failed");
206#endif
207 (void) close(s);
208 s = -1;
209 /* 472 /*
210 * A long running process might get its TCP 473 * A long running process might get its TCP
211 * connection reset if the remote server was 474 * connection reset if the remote server was
@@ -217,35 +480,32 @@ res_send(buf, buflen, answer, anslen)
217 */ 480 */
218 if (terrno == ECONNRESET && !connreset) { 481 if (terrno == ECONNRESET && !connreset) {
219 connreset = 1; 482 connreset = 1;
220 ns--; 483 res_close();
484 goto same_ns;
221 } 485 }
222 continue; 486 res_close();
487 goto next_ns;
223 } 488 }
224 cp = answer; 489 resplen = _getshort(ans);
225 if ((resplen = ntohs(*(u_short *)cp)) > anslen) { 490 if (resplen > anssiz) {
226#ifdef DEBUG 491 Dprint(_resp->options & RES_DEBUG,
227 if (_res.options & RES_DEBUG) 492 (stdout, ";; response truncated\n")
228 fprintf(stderr, 493 );
229 ";; response truncated\n");
230#endif
231 len = anslen;
232 truncated = 1; 494 truncated = 1;
495 len = anssiz;
233 } else 496 } else
234 len = resplen; 497 len = resplen;
498 cp = ans;
235 while (len != 0 && 499 while (len != 0 &&
236 (n = read(s, (char *)cp, (int)len)) > 0) { 500 (n = read(s, (char *)cp, (int)len)) > 0) {
237 cp += n; 501 cp += n;
238 len -= n; 502 len -= n;
239 } 503 }
240 if (n <= 0) { 504 if (n <= 0) {
241 terrno = errno; 505 terrno = errno;
242#ifdef DEBUG 506 Perror(stderr, "read(vc)", errno);
243 if (_res.options & RES_DEBUG) 507 res_close();
244 perror("read failed"); 508 goto next_ns;
245#endif
246 (void) close(s);
247 s = -1;
248 continue;
249 } 509 }
250 if (truncated) { 510 if (truncated) {
251 /* 511 /*
@@ -253,40 +513,79 @@ res_send(buf, buflen, answer, anslen)
253 * so connection stays in synch. 513 * so connection stays in synch.
254 */ 514 */
255 anhp->tc = 1; 515 anhp->tc = 1;
256 len = resplen - anslen; 516 len = resplen - anssiz;
257 while (len != 0) { 517 while (len != 0) {
258 n = (len > sizeof(junk) ? 518 char junk[PACKETSZ];
259 sizeof(junk) : len); 519
520 n = (len > sizeof(junk)
521 ? sizeof(junk)
522 : len);
260 if ((n = read(s, junk, n)) > 0) 523 if ((n = read(s, junk, n)) > 0)
261 len -= n; 524 len -= n;
262 else 525 else
263 break; 526 break;
264 } 527 }
265 } 528 }
529 /*
530 * The calling applicating has bailed out of
531 * a previous call and failed to arrange to have
532 * the circuit closed or the server has got
533 * itself confused. Anyway drop the packet and
534 * wait for the correct one.
535 */
536 if (hp->id != anhp->id) {
537 DprintQ((_resp->options & RES_DEBUG) ||
538 (_resp->pfcode & RES_PRF_REPLY),
539 (stdout, ";; old answer (unexpected):\n"),
540 ans, (resplen>anssiz)?anssiz:resplen);
541 goto read_len;
542 }
266 } else { 543 } else {
267 /* 544 /*
268 * Use datagrams. 545 * Use datagrams.
269 */ 546 */
270 if (s < 0) { 547 struct pollfd pfd;
271 s = socket(AF_INET, SOCK_DGRAM, 0); 548 int timeout;
549 struct sockaddr_storage from;
550 socklen_t fromlen;
551
552 if ((s < 0) || vc || (af != nsap->sa_family)) {
553 if (vc)
554 res_close();
555 af = nsap->sa_family;
556 s = socket(af, SOCK_DGRAM, 0);
272 if (s < 0) { 557 if (s < 0) {
558#if !CAN_RECONNECT
559 bad_dg_sock:
560#endif
273 terrno = errno; 561 terrno = errno;
274#ifdef DEBUG 562 Perror(stderr, "socket(dg)", errno);
275 if (_res.options & RES_DEBUG) 563#if 0
276 perror("socket (dg) failed"); 564 return (-1);
565#else
566 badns |= (1 << ns);
567 res_close();
568 goto next_ns;
277#endif 569#endif
278 continue;
279 } 570 }
571#ifdef IPV6_MINMTU
572 if (af == AF_INET6) {
573 const int yes = 1;
574 (void)setsockopt(s, IPPROTO_IPV6,
575 IPV6_USE_MIN_MTU, &yes,
576 sizeof(yes));
577 }
578#endif
579 connected = 0;
280 } 580 }
281 /* 581 /*
282 * I'm tired of answering this question, so:
283 * On a 4.3BSD+ machine (client and server, 582 * On a 4.3BSD+ machine (client and server,
284 * actually), sending to a nameserver datagram 583 * actually), sending to a nameserver datagram
285 * port with no nameserver will cause an 584 * port with no nameserver will cause an
286 * ICMP port unreachable message to be returned. 585 * ICMP port unreachable message to be returned.
287 * If our datagram socket is "connected" to the 586 * If our datagram socket is "connected" to the
288 * server, we get an ECONNREFUSED error on the next 587 * server, we get an ECONNREFUSED error on the next
289 * socket operation, and select returns if the 588 * socket operation, and poll returns if the
290 * error message is received. We can thus detect 589 * error message is received. We can thus detect
291 * the absence of a nameserver without timing out. 590 * the absence of a nameserver without timing out.
292 * If we have sent queries to at least two servers, 591 * If we have sent queries to at least two servers,
@@ -294,31 +593,28 @@ res_send(buf, buflen, answer, anslen)
294 * as we wish to receive answers from the first 593 * as we wish to receive answers from the first
295 * server to respond. 594 * server to respond.
296 */ 595 */
297 if (_res.nscount == 1 || (try == 0 && ns == 0)) { 596 if (!(_resp->options & RES_INSECURE1) &&
597 (_resp->nscount == 1 || (try == 0 && ns == 0))) {
298 /* 598 /*
299 * Don't use connect if we might 599 * Connect only if we are sure we won't
300 * still receive a response 600 * receive a response from another server.
301 * from another server.
302 */ 601 */
303 if (connected == 0) { 602 if (!connected) {
304 if (connect(s, 603 if (connect(s, nsap, salen) < 0) {
305 (struct sockaddr *) 604 Aerror(stderr,
306 &_res.nsaddr_list[ns], 605 "connect(dg)",
307 sizeof(struct sockaddr)) < 0) { 606 errno, nsap);
308#ifdef DEBUG 607 badns |= (1 << ns);
309 if (_res.options & RES_DEBUG) 608 res_close();
310 perror("connect"); 609 goto next_ns;
311#endif
312 continue;
313 } 610 }
314 connected = 1; 611 connected = 1;
315 } 612 }
316 if (send(s, buf, buflen, 0) != buflen) { 613 if (send(s, (char*)buf, buflen, 0) != buflen) {
317#ifdef DEBUG 614 Perror(stderr, "send", errno);
318 if (_res.options & RES_DEBUG) 615 badns |= (1 << ns);
319 perror("send"); 616 res_close();
320#endif 617 goto next_ns;
321 continue;
322 } 618 }
323 } else { 619 } else {
324 /* 620 /*
@@ -326,134 +622,213 @@ res_send(buf, buflen, answer, anslen)
326 * for responses from more than one server. 622 * for responses from more than one server.
327 */ 623 */
328 if (connected) { 624 if (connected) {
329 (void) connect(s, &no_addr, 625#if CAN_RECONNECT
330 sizeof(no_addr)); 626#ifdef INET6
627 /* XXX: any errornous address */
628#endif /* INET6 */
629 struct sockaddr_in no_addr;
630
631 no_addr.sin_family = AF_INET;
632 no_addr.sin_addr.s_addr = INADDR_ANY;
633 no_addr.sin_port = 0;
634 (void) connect(s,
635 (struct sockaddr *)
636 &no_addr,
637 sizeof(no_addr));
638#else
639 int s1 = socket(af, SOCK_DGRAM,0);
640 if (s1 < 0)
641 goto bad_dg_sock;
642 (void) dup2(s1, s);
643 (void) close(s1);
644 Dprint(_resp->options & RES_DEBUG,
645 (stdout, ";; new DG socket\n"))
646#endif
647#ifdef IPV6_MINMTU
648 if (af == AF_INET6) {
649 const int yes = 1;
650 (void)setsockopt(s, IPPROTO_IPV6,
651 IPV6_USE_MIN_MTU, &yes,
652 sizeof(yes));
653 }
654#endif
331 connected = 0; 655 connected = 0;
656 errno = 0;
332 } 657 }
333 if (sendto(s, buf, buflen, 0, 658 if (sendto(s, (char*)buf, buflen, 0,
334 (struct sockaddr *)&_res.nsaddr_list[ns], 659 nsap, salen) != buflen) {
335 sizeof(struct sockaddr)) != buflen) { 660 Aerror(stderr, "sendto", errno, nsap);
336#ifdef DEBUG 661 badns |= (1 << ns);
337 if (_res.options & RES_DEBUG) 662 res_close();
338 perror("sendto"); 663 goto next_ns;
339#endif
340 continue;
341 } 664 }
342 } 665 }
343 666
344 /* 667 /*
345 * Wait for reply 668 * Wait for reply
346 */ 669 */
347 timeout.tv_sec = (_res.retrans << try); 670 timeout = 1000 * (_resp->retrans << try);
348 if (try > 0) 671 if (try > 0)
349 timeout.tv_sec /= _res.nscount; 672 timeout /= _resp->nscount;
350 if ((long) timeout.tv_sec <= 0) 673 if (timeout < 1000)
351 timeout.tv_sec = 1; 674 timeout = 1000;
352 timeout.tv_usec = 0; 675 wait:
353wait: 676 pfd.fd = s;
354 FD_ZERO(&dsmask); 677 pfd.events = POLLIN;
355 FD_SET(s, &dsmask); 678 n = poll(&pfd, 1, timeout);
356 n = select(s+1, &dsmask, (fd_set *)NULL,
357 (fd_set *)NULL, &timeout);
358 if (n < 0) { 679 if (n < 0) {
359#ifdef DEBUG 680 if (errno == EINTR)
360 if (_res.options & RES_DEBUG) 681 goto wait;
361 perror("select"); 682 Perror(stderr, "poll", errno);
362#endif 683 res_close();
363 continue; 684 goto next_ns;
364 } 685 }
365 if (n == 0) { 686 if (n == 0) {
366 /* 687 /*
367 * timeout 688 * timeout
368 */ 689 */
369#ifdef DEBUG 690 Dprint(_resp->options & RES_DEBUG,
370 if (_res.options & RES_DEBUG) 691 (stdout, ";; timeout\n"));
371 printf(";; timeout\n");
372#endif
373 gotsomewhere = 1; 692 gotsomewhere = 1;
374 continue; 693 res_close();
694 goto next_ns;
375 } 695 }
376 if ((resplen = recv(s, answer, anslen, 0)) <= 0) { 696 errno = 0;
377#ifdef DEBUG 697 fromlen = sizeof(from);
378 if (_res.options & RES_DEBUG) 698 resplen = recvfrom(s, (char*)ans, anssiz, 0,
379 perror("recvfrom"); 699 (struct sockaddr *)&from, &fromlen);
380#endif 700 if (resplen <= 0) {
381 continue; 701 Perror(stderr, "recvfrom", errno);
702 res_close();
703 goto next_ns;
382 } 704 }
383 gotsomewhere = 1; 705 gotsomewhere = 1;
384 if (id != anhp->id) { 706 if (hp->id != anhp->id) {
385 /* 707 /*
386 * response from old query, ignore it 708 * response from old query, ignore it.
709 * XXX - potential security hazard could
710 * be detected here.
387 */ 711 */
388#ifdef DEBUG 712 DprintQ((_resp->options & RES_DEBUG) ||
389 if ((_res.options & RES_DEBUG) || 713 (_resp->pfcode & RES_PRF_REPLY),
390 (_res.pfcode & RES_PRF_REPLY)) { 714 (stdout, ";; old answer:\n"),
391 printf(";; old answer:\n"); 715 ans, (resplen>anssiz)?anssiz:resplen);
392 __p_query(answer); 716 goto wait;
393 } 717 }
718#if CHECK_SRVR_ADDR
719 if (!(_resp->options & RES_INSECURE1) &&
720 !res_isourserver((struct sockaddr_in *)&from)) {
721 /*
722 * response from wrong server? ignore it.
723 * XXX - potential security hazard could
724 * be detected here.
725 */
726 DprintQ((_resp->options & RES_DEBUG) ||
727 (_resp->pfcode & RES_PRF_REPLY),
728 (stdout, ";; not our server:\n"),
729 ans, (resplen>anssiz)?anssiz:resplen);
730 goto wait;
731 }
394#endif 732#endif
733 if (!(_resp->options & RES_INSECURE2) &&
734 !res_queriesmatch(buf, buf + buflen,
735 ans, ans + anssiz)) {
736 /*
737 * response contains wrong query? ignore it.
738 * XXX - potential security hazard could
739 * be detected here.
740 */
741 DprintQ((_resp->options & RES_DEBUG) ||
742 (_resp->pfcode & RES_PRF_REPLY),
743 (stdout, ";; wrong query name:\n"),
744 ans, (resplen>anssiz)?anssiz:resplen);
395 goto wait; 745 goto wait;
396 } 746 }
397 if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || 747 if (anhp->rcode == SERVFAIL ||
748 anhp->rcode == NOTIMP ||
398 anhp->rcode == REFUSED) { 749 anhp->rcode == REFUSED) {
399#ifdef DEBUG 750 DprintQ(_resp->options & RES_DEBUG,
400 if (_res.options & RES_DEBUG) { 751 (stdout, "server rejected query:\n"),
401 printf("server rejected query:\n"); 752 ans, (resplen>anssiz)?anssiz:resplen);
402 __p_query(answer); 753 badns |= (1 << ns);
403 } 754 res_close();
404#endif 755 /* don't retry if called from dig */
405 badns |= (1<<ns); 756 if (!_resp->pfcode)
406 continue; 757 goto next_ns;
407 } 758 }
408 if (!(_res.options & RES_IGNTC) && anhp->tc) { 759 if (!(_resp->options & RES_IGNTC) && anhp->tc) {
409 /* 760 /*
410 * get rest of answer; 761 * get rest of answer;
411 * use TCP with same server. 762 * use TCP with same server.
412 */ 763 */
413#ifdef DEBUG 764 Dprint(_resp->options & RES_DEBUG,
414 if (_res.options & RES_DEBUG) 765 (stdout, ";; truncated answer\n"));
415 printf(";; truncated answer\n");
416#endif
417 (void) close(s);
418 s = -1;
419 v_circuit = 1; 766 v_circuit = 1;
420 goto usevc; 767 res_close();
768 goto same_ns;
421 } 769 }
422 } 770 } /*if vc/dg*/
423#ifdef DEBUG 771 Dprint((_resp->options & RES_DEBUG) ||
424 if (_res.options & RES_DEBUG) 772 ((_resp->pfcode & RES_PRF_REPLY) &&
425 printf(";; got answer:\n"); 773 (_resp->pfcode & RES_PRF_HEAD1)),
426 if ((_res.options & RES_DEBUG) || 774 (stdout, ";; got answer:\n"));
427 (_res.pfcode & RES_PRF_REPLY)) 775 DprintQ((_resp->options & RES_DEBUG) ||
428 __p_query(answer); 776 (_resp->pfcode & RES_PRF_REPLY),
429#endif 777 (stdout, "%s", ""),
778 ans, (resplen>anssiz)?anssiz:resplen);
430 /* 779 /*
431 * If using virtual circuits, we assume that the first server 780 * If using virtual circuits, we assume that the first server
432 * is preferred * over the rest (i.e. it is on the local 781 * is preferred over the rest (i.e. it is on the local
433 * machine) and only keep that one open. 782 * machine) and only keep that one open.
434 * If we have temporarily opened a virtual circuit, 783 * If we have temporarily opened a virtual circuit,
435 * or if we haven't been asked to keep a socket open, 784 * or if we haven't been asked to keep a socket open,
436 * close the socket. 785 * close the socket.
437 */ 786 */
438 if ((v_circuit && 787 if ((v_circuit && (!(_resp->options & RES_USEVC) || ns != 0)) ||
439 ((_res.options & RES_USEVC) == 0 || ns != 0)) || 788 !(_resp->options & RES_STAYOPEN)) {
440 (_res.options & RES_STAYOPEN) == 0) { 789 res_close();
441 (void) close(s); 790 }
442 s = -1; 791 if (Rhook) {
792 int done = 0, loops = 0;
793
794 do {
795 res_sendhookact act;
796
797 act = (*Rhook)((struct sockaddr_in *)nsap,
798 buf, buflen,
799 ans, anssiz, &resplen);
800 switch (act) {
801 case res_goahead:
802 case res_done:
803 done = 1;
804 break;
805 case res_nextns:
806 res_close();
807 goto next_ns;
808 case res_modified:
809 /* give the hook another try */
810 if (++loops < 42) /*doug adams*/
811 break;
812 /*FALLTHROUGH*/
813 case res_error:
814 /*FALLTHROUGH*/
815 default:
816 return (-1);
817 }
818 } while (!done);
819
443 } 820 }
444 return (resplen); 821 return (resplen);
445 } 822 next_ns: ;
446 } 823 } /*foreach ns*/
447 if (s >= 0) { 824 } /*foreach retry*/
448 (void) close(s); 825 res_close();
449 s = -1; 826 if (!v_circuit) {
450 } 827 if (!gotsomewhere)
451 if (v_circuit == 0)
452 if (gotsomewhere == 0)
453 errno = ECONNREFUSED; /* no nameservers found */ 828 errno = ECONNREFUSED; /* no nameservers found */
454 else 829 else
455 errno = ETIMEDOUT; /* no answer obtained */ 830 errno = ETIMEDOUT; /* no answer obtained */
456 else 831 } else
457 errno = terrno; 832 errno = terrno;
458 return (-1); 833 return (-1);
459} 834}
@@ -465,10 +840,14 @@ wait:
465 * 840 *
466 * This routine is not expected to be user visible. 841 * This routine is not expected to be user visible.
467 */ 842 */
468_res_close() 843void
844res_close(void)
469{ 845{
470 if (s != -1) { 846 if (s >= 0) {
471 (void) close(s); 847 (void) close(s);
472 s = -1; 848 s = -1;
849 connected = 0;
850 vc = 0;
851 af = 0;
473 } 852 }
474} 853}
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
index 99abe17f03..e820ea25ed 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.21 2007/05/31 19:19:30 jmc Exp $
2.\" 2.\"
3.\" Copyright (c) 1985, 1991, 1993 3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,11 +27,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93 30.Dd $Mdocdate: May 31 2007 $
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 ,
@@ -50,69 +44,76 @@
50.Fd #include <netinet/in.h> 44.Fd #include <netinet/in.h>
51.Fd #include <arpa/nameser.h> 45.Fd #include <arpa/nameser.h>
52.Fd #include <resolv.h> 46.Fd #include <resolv.h>
47.Ft int
53.Fo res_query 48.Fo res_query
54.Fa "char *dname" 49.Fa "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
100These routines are used for making, sending and interpreting 101These routines are used for making, sending, and interpreting
101query and reply messages with Internet domain name servers. 102query and reply messages with Internet domain name servers.
102.Pp 103.Pp
103Global configuration and state information that is used by the 104Global configuration and state information that is used by the
104resolver routines is kept in the structure 105resolver routines is kept in the structure
105.Em _res . 106.Li _res .
106Most of the values have reasonable defaults and can be ignored. 107Most of the values have reasonable defaults and can be ignored.
107Options 108Options stored in
108stored in 109.Li _res.options
109.Em _res.options
110are defined in 110are defined in
111.Pa resolv.h 111.Aq Pa resolv.h
112and are as follows. 112and are as follows.
113Options are stored as a simple bit mask containing the bitwise ``or'' 113Options are stored as a simple bit mask containing the bitwise
114.Tn OR
114of the options enabled. 115of the options enabled.
115.Bl -tag -width RES_DEFNAMES 116.Bl -tag -width RES_USE_INET6
116.It Dv RES_INIT 117.It Dv RES_INIT
117True if the initial name server address and default domain name are 118True if the initial name server address and default domain name are
118initialized (i.e., 119initialized (i.e.,
@@ -137,8 +138,7 @@ Used with
137.Dv RES_USEVC 138.Dv RES_USEVC
138to keep the 139to keep the
139.Tn TCP 140.Tn TCP
140connection open between 141connection open between queries.
141queries.
142This is useful only in programs that regularly do many queries. 142This is useful only in programs that regularly do many queries.
143.Tn UDP 143.Tn UDP
144should be the normal mode used. 144should be the normal mode used.
@@ -165,16 +165,28 @@ will search for host names in the current domain and in parent domains; see
165This is used by the standard host lookup routine 165This is used by the standard host lookup routine
166.Xr gethostbyname 3 . 166.Xr gethostbyname 3 .
167This option is enabled by default. 167This option is enabled by default.
168.It Dv RES_USE_INET6
169Enables support for IPv6-only applications.
170This causes IPv4 addresses to be returned as an IPv4 mapped address.
171For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1.
172The option is not meaningful on
173.Ox .
174.It Dv RES_USE_EDNS0
175Enables support for OPT pseudo-RR for EDNS0 extension.
176With this option, resolver code will attach OPT pseudo-RR into DNS queries,
177to inform of our receive buffer size.
178The option will allow DNS servers to take advantage of non-default receive
179buffer size, and to send larger replies.
180DNS query packets with EDNS0 extension is not compatible with
181non-EDNS0 DNS servers.
168.El 182.El
169.Pp 183.Pp
170The 184The
171.Fn res_init 185.Fn res_init
172routine 186routine reads the configuration file (if any; see
173reads the configuration file (if any; see
174.Xr resolv.conf 5 ) 187.Xr resolv.conf 5 )
175to get the default domain name, 188to get the default domain name, search list, and the Internet address
176search list and 189of the local name server(s).
177the Internet address of the local name server(s).
178If no server is configured, the host running 190If no server is configured, the host running
179the resolver is tried. 191the resolver is tried.
180The current domain name is defined by the hostname 192The current domain name is defined by the hostname
@@ -212,20 +224,26 @@ The query requests information of the specified
212.Fa type 224.Fa type
213and 225and
214.Fa class 226.Fa class
215for the specified fully-qualified domain name 227for the specified fully qualified domain name
216.Fa dname . 228.Fa dname .
217The reply message is left in the 229The reply message is left in the
218.Fa answer 230.Fa answer
219buffer with length 231buffer with length
220.Fa anslen 232.Fa anslen
221supplied by the caller. 233supplied by the caller.
234Values for the
235.Fa class
236and
237.Fa type
238fields
239are defined in
240.Aq Pa arpa/nameser.h .
222.Pp 241.Pp
223The 242The
224.Fn res_search 243.Fn res_search
225routine makes a query and awaits a response like 244routine makes a query and awaits a response like
226.Fn res_query , 245.Fn res_query ,
227but in addition, it implements the default and search rules 246but in addition, it implements the default and search rules controlled by the
228controlled by the
229.Dv RES_DEFNAMES 247.Dv RES_DEFNAMES
230and 248and
231.Dv RES_DNSRCH 249.Dv RES_DNSRCH
@@ -236,11 +254,9 @@ The remaining routines are lower-level routines used by
236.Fn res_query . 254.Fn res_query .
237The 255The
238.Fn res_mkquery 256.Fn res_mkquery
239function 257function constructs a standard query message and places it in
240constructs a standard query message and places it in
241.Fa buf . 258.Fa buf .
242It returns the size of the query, or \-1 if the query is 259It returns the size of the query, or \-1 if the query is larger than
243larger than
244.Fa buflen . 260.Fa buflen .
245The query type 261The query type
246.Fa op 262.Fa op
@@ -250,26 +266,23 @@ but can be any of the query types defined in
250.Aq Pa arpa/nameser.h . 266.Aq Pa arpa/nameser.h .
251The domain name for the query is given by 267The domain name for the query is given by
252.Fa dname . 268.Fa dname .
253.Fa Newrr 269.Fa newrr
254is currently unused but is intended for making update messages. 270is currently unused but is intended for making update messages.
255.Pp 271.Pp
256The 272The
257.Fn res_send 273.Fn res_send
258routine 274routine sends a pre-formatted query and returns an answer.
259sends a pre-formatted query and returns an answer.
260It will call 275It will call
261.Fn res_init 276.Fn res_init
262if 277if
263.Dv RES_INIT 278.Dv RES_INIT
264is not set, send the query to the local name server, and 279is not set, send the query to the local name server, and
265handle timeouts and retries. 280handle timeouts and retries.
266The length of the reply message is returned, or 281The length of the reply message is returned, or \-1 if there were errors.
267\-1 if there were errors.
268.Pp 282.Pp
269The 283The
270.Fn dn_comp 284.Fn dn_comp
271function 285function compresses the domain name
272compresses the domain name
273.Fa exp_dn 286.Fa exp_dn
274and stores it in 287and stores it in
275.Fa comp_dn . 288.Fa comp_dn .
@@ -278,24 +291,23 @@ The size of the array pointed to by
278.Fa comp_dn 291.Fa comp_dn
279is given by 292is given by
280.Fa length . 293.Fa length .
281The compression uses 294The compression uses an array of pointers
282an array of pointers
283.Fa dnptrs 295.Fa dnptrs
284to previously-compressed names in the current message. 296to previously compressed names in the current message.
285The first pointer points to 297The first pointer points
286to the beginning of the message and the list ends with 298to the beginning of the message and the list ends with
287.Dv NULL . 299.Dv NULL .
288The limit to the array is specified by 300The limit to the array is specified by
289.Fa lastdnptr . 301.Fa lastdnptr .
290A side effect of 302A side effect of
291.Fn dn_comp 303.Fn dn_comp
292is to update the list of pointers for 304is to update the list of pointers for labels inserted into the message
293labels inserted into the message
294as the name is compressed. 305as the name is compressed.
295If 306If
296.Em dnptr 307.Fa dnptrs
297is 308is
298.Dv NULL, names are not compressed. 309.Dv NULL ,
310names are not compressed.
299If 311If
300.Fa lastdnptr 312.Fa lastdnptr
301is 313is
@@ -304,10 +316,9 @@ the list of labels is not updated.
304.Pp 316.Pp
305The 317The
306.Fn dn_expand 318.Fn dn_expand
307entry 319entry expands the compressed domain name
308expands the compressed domain name
309.Fa comp_dn 320.Fa comp_dn
310to a full domain name 321to a full domain name.
311The compressed name is contained in a query or reply message; 322The compressed name is contained in a query or reply message;
312.Fa msg 323.Fa msg
313is a pointer to the beginning of the message. 324is a pointer to the beginning of the message.
@@ -317,28 +328,27 @@ which is of size
317.Fa length . 328.Fa length .
318The size of compressed name is returned or \-1 if there was an error. 329The size of compressed name is returned or \-1 if there was an error.
319.Sh FILES 330.Sh FILES
320.Bl -tag -width Pa 331.Bl -tag -width "/etc/resolv.confXX"
321/etc/resolv.conf 332.It Pa /etc/resolv.conf
322The configuration file 333The configuration file.
323see
324.Xr resolv.conf 5 .
325.El 334.El
326.Sh SEE ALSO 335.Sh SEE ALSO
327.Xr gethostbyname 3 , 336.Xr gethostbyname 3 ,
328.Xr named 8 ,
329.Xr resolv.conf 5 , 337.Xr resolv.conf 5 ,
330.Xr hostname 7 , 338.Xr hostname 7 ,
339.Xr named 8
331.Pp 340.Pp
332.%T RFC1032 , 341.%T RFC 974 ,
333.%T RFC1033 , 342.%T RFC 1032 ,
334.%T RFC1034 , 343.%T RFC 1033 ,
335.%T RFC1035 , 344.%T RFC 1034 ,
336.%T RFC974 345.%T RFC 1035 ,
346.%T RFC 1535
337.Rs 347.Rs
338.%T "Name Server Operations Guide for BIND" 348.%T "Name Server Operations Guide for BIND"
339.Re 349.Re
340.Sh HISTORY 350.Sh HISTORY
341The 351The
342.Nm 352.Nm
343function appeared in 353function appeared in
344.Bx 4.3 . 354.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
52int
53rresvport(int *alport)
54{
55 return rresvport_af(alport, AF_INET);
56}
57
58
59int
60rresvport_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
47size_t
48inet6_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
61struct cmsghdr *
62inet6_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
83int
84inet6_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
112int
113inet6_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
137int
138inet6_rthdr_reverse(in, out)
139 const struct cmsghdr *in;
140 struct cmsghdr *out;
141{
142
143 return (-1);
144}
145#endif
146
147int
148inet6_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
170struct in6_addr *
171inet6_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
196int
197inet6_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
226socklen_t
227inet6_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
237void *
238inet6_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
263int
264inet6_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
284int
285inet6_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
326int
327inet6_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
351struct in6_addr *
352inet6_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/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
38static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94";
39#else
40static char rcsid[] = "$NetBSD: send.c,v 1.6 1995/02/25 06:21:02 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
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
49ssize_t 36ssize_t
50send(s, msg, len, flags) 37send(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/sethostent.c b/src/lib/libc/net/sethostent.c
index 00f6499695..6f6d0e405a 100644
--- a/src/lib/libc/net/sethostent.c
+++ b/src/lib/libc/net/sethostent.c
@@ -1,5 +1,4 @@
1/* $NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $ */ 1/* $OpenBSD: sethostent.c,v 1.9 2005/08/06 20:30:04 espie Exp $ */
2
3/* 2/*
4 * Copyright (c) 1985, 1993 3 * Copyright (c) 1985, 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,30 +28,30 @@
33 * SUCH DAMAGE. 28 * SUCH DAMAGE.
34 */ 29 */
35 30
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] = "$NetBSD: sethostent.c,v 1.4 1995/02/25 06:21:03 cgd Exp $";
41#endif
42#endif /* LIBC_SCCS and not lint */
43
44#include <sys/param.h> 31#include <sys/param.h>
45#include <netinet/in.h> 32#include <netinet/in.h>
46#include <arpa/nameser.h> 33#include <arpa/nameser.h>
47#include <netdb.h> 34#include <netdb.h>
48#include <resolv.h> 35#include <resolv.h>
49 36
37#include "thread_private.h"
38
50void 39void
51sethostent(stayopen) 40sethostent(int stayopen)
52{ 41{
42 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
43
44 if (_res_init(0) == -1)
45 return;
53 if (stayopen) 46 if (stayopen)
54 _res.options |= RES_STAYOPEN | RES_USEVC; 47 _resp->options |= RES_STAYOPEN | RES_USEVC;
55} 48}
56 49
57void 50void
58endhostent() 51endhostent(void)
59{ 52{
60 _res.options &= ~(RES_STAYOPEN | RES_USEVC); 53 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
61 _res_close(); 54
55 _resp->options &= ~(RES_STAYOPEN | RES_USEVC);
56 res_close();
62} 57}
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c
new file mode 100644
index 0000000000..a22d49d047
--- /dev/null
+++ b/src/lib/libc/net/vars6.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: vars6.c,v 1.2 2003/05/10 10:56:47 jmc Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <netinet/in.h>
34
35/*
36 * Definitions of some constant IPv6 addresses.
37 */
38const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
39const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
40const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
41const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
42
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index 782a4ab022..09db4ce793 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,24 +1,29 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91 1# $OpenBSD: Makefile.inc,v 1.39 2008/08/22 17:14:56 otto Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
3 2
4# stdlib sources 3# stdlib sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
6 5
7SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
8 exit.c getenv.c getopt.c heapsort.c l64a.c malloc.c merge.c \ 7 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 putenv.c qsort.c radixsort.c rand.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 10 random.c realpath.c setenv.c strtoimax.c strtod.c strtof.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_ARCH} == "m68k")
15SRCS+= abs.S div.c labs.c ldiv.c 16SRCS+= abs.S div.c labs.c ldiv.c
17LSRCS+= abs.c
16.elif (${MACHINE_ARCH} == "i386") 18.elif (${MACHINE_ARCH} == "i386")
17SRCS+= abs.S div.S labs.S ldiv.S 19SRCS+= abs.S div.S labs.S ldiv.S
20LSRCS+= abs.c div.c labs.c ldiv.c
18.elif (${MACHINE_ARCH} == "ns32k") 21.elif (${MACHINE_ARCH} == "ns32k")
19SRCS+= abs.S div.c labs.c ldiv.c 22SRCS+= abs.S div.c labs.c ldiv.c
23LSRCS+= abs.c
20.elif (${MACHINE_ARCH} == "tahoe") 24.elif (${MACHINE_ARCH} == "tahoe")
21SRCS+= abs.S div.c labs.c ldiv.c 25SRCS+= abs.S div.c labs.c ldiv.c
26LSRCS+= abs.c
22.elif (${MACHINE_ARCH} == "vax") 27.elif (${MACHINE_ARCH} == "vax")
23SRCS+= abs.c div.c labs.c ldiv.c 28SRCS+= abs.c div.c labs.c ldiv.c
24.elif (${MACHINE_ARCH} == "alpha") 29.elif (${MACHINE_ARCH} == "alpha")
@@ -28,18 +33,41 @@ SRCS+= abs.c div.c labs.c ldiv.c
28SRCS+= abs.c div.c labs.c ldiv.c 33SRCS+= abs.c div.c labs.c ldiv.c
29.endif 34.endif
30 35
31MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \ 36.if (${MACHINE_ARCH} == "vax") || (${MACHINE_ARCH} == "m68k")
32 calloc.3 div.3 exit.3 free.3 getenv.3 getopt.3 labs.3 ldiv.3 \ 37SRCS+= insque.S remque.S
33 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \ 38.else
34 rand.3 random.3 realloc.3 realpath.3 strtod.3 strtol.3 strtoul.3 \ 39SRCS+= insque.c remque.c
35 system.3 40.endif
41
42MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
43 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
44 getsubopt.3 hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 \
45 lldiv.3 lsearch.3 malloc.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \
46 rand.3 random.3 realpath.3 strtod.3 strtonum.3 strtol.3 strtoul.3 \
47 system.3 tsearch.3
36 48
49MLINKS+=exit.3 _Exit.3
50MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
37MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 51MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
52MLINKS+=getopt_long.3 getopt_long_only.3
53MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
54MLINKS+=insque.3 remque.3
55MLINKS+=labs.3 llabs.3
56MLINKS+=lsearch.3 lfind.3
57MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
58MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
38MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 59MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
39MLINKS+=rand.3 srand.3 60MLINKS+=radixsort.3 sradixsort.3
40MLINKS+=strtol.3 strtoq.3 61MLINKS+=rand.3 srand.3 rand.3 rand_r.3
41MLINKS+=strtoul.3 strtouq.3 62MLINKS+=random.3 initstate.3 random.3 setstate.3
42MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 63MLINKS+=random.3 srandom.3 random.3 srandomdev.3
43MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 64MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
44MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 65MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
45MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 66MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
67MLINKS+=strtod.3 strtof.3
68MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3
69MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 strtoul.3 strtoumax.3
70MLINKS+=tsearch.3 tfind.3
71MLINKS+=tsearch.3 tdelete.3
72MLINKS+=tsearch.3 twalk.3
73MLINKS+=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..5a2291a931
--- /dev/null
+++ b/src/lib/libc/stdlib/_Exit.c
@@ -0,0 +1,22 @@
1/* $OpenBSD: _Exit.c,v 1.2 2005/08/08 08:05:36 espie 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. As such it is safest to *not* flush
15 * stdio buffers or remove temporary files. This is also consistent
16 * with most other implementations.
17 */
18void
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..6eec5ce3b3
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,133 @@
1.\" $OpenBSD: a64l.3,v 1.10 2007/05/31 19:19:31 jmc 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: May 31 2007 $
18.Dt A64L 3
19.Os
20.Sh NAME
21.Nm a64l ,
22.Nm l64a
23.Nd convert between 32-bit integer and radix-64 ASCII string
24.Sh SYNOPSIS
25.Fd #include <stdlib.h>
26.Ft long
27.Fn a64l "const char *s"
28.Ft char *
29.Fn l64a "long l"
30.Sh DESCRIPTION
31The
32.Fn a64l
33and
34.Fn l64a
35functions are used to maintain numbers stored in radix-64
36.Tn ASCII
37characters.
38This is a notation by which 32-bit integers
39can be represented by up to six characters; each character represents a
40.Dq digit
41in a radix-64 notation.
42.Pp
43The characters used to represent digits are
44.Ql \&.
45for 0,
46.Ql /
47for 1,
48.Ql 0
49through
50.Ql 9
51for 2-11,
52.Ql A
53through
54.Ql Z
55for 12-37, and
56.Ql a
57through
58.Ql z
59for 38-63.
60.Pp
61The
62.Fn a64l
63function takes a pointer to a NUL-terminated radix-64 representation
64and returns a corresponding 32-bit value.
65If the string pointed to by
66.Fa s
67contains more than six characters,
68.Fn a64l
69will use the first six.
70.Fn a64l
71scans the character string from left to right, decoding
72each character as a 6-bit radix-64 number.
73If a long integer is
74larger than 32 bits, the return value will be sign-extended.
75.Pp
76.Fn l64a
77takes a long integer argument
78.Fa l
79and returns a pointer to the corresponding radix-64 representation.
80.Sh RETURN VALUES
81On success,
82.Fn a64l
83returns a 32-bit representation of
84.Fa s .
85If
86.Fa s
87is a null pointer or if it contains digits other than those described above,
88.Fn a64l
89returns \-1 and sets the global variable
90.Va errno
91to
92.Er EINVAL .
93.Pp
94On success,
95.Fn l64a
96returns a pointer to a string containing the radix-64 representation of
97.Fa l .
98If
99.Fa l
100is 0,
101.Fn l64a
102returns a pointer to the empty string.
103If
104.Fa l
105is negative,
106.Fn l64a
107returns a null pointer and sets the global variable
108.Va errno
109to
110.Er EINVAL .
111.Sh WARNINGS
112The value returned by
113.Fn l64a
114is a pointer into a static buffer, the contents of which
115will be overwritten by subsequent calls.
116.Pp
117The value returned by
118.Fn a64l
119may be incorrect if the value is too large; for that reason, only strings
120that resulted from a call to
121.Fn l64a
122should be used to call
123.Fn a64l .
124.Pp
125If a long integer is larger than 32 bits, only the low-order
12632 bits are used.
127.Sh STANDARDS
128The
129.Fn a64l
130and
131.Fn l64a
132functions conform to
133.St -xpg4.2 .
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
index 03fc77e034..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>
7static char *rcsid = "$NetBSD: a64l.c,v 1.3 1995/05/11 23:04:47 jtc Exp $"; 8#include <stdlib.h>
8#endif
9 9
10long 10long
11a64l(s) 11a64l(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..4ec85882b2 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,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: @(#)abort.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: abort.3,v 1.8 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ABORT 3 35.Dt ABORT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,23 +44,20 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abort 46.Fn abort
52function causes abnormal program termination to occur, unless the 47function causes abnormal program termination to occur, unless the signal
53signal
54.Dv SIGABRT 48.Dv SIGABRT
55is being caught and the signal handler does not return. 49is being caught and the signal handler does not return.
56.Pp 50.Pp
57No open streams are closed or flushed. 51Any open streams are flushed and closed.
58.Sh RETURN VALUES 52.Sh RETURN VALUES
59The 53The
60.Nm abort 54.Fn abort
61function 55function never returns.
62never returns.
63.Sh SEE ALSO 56.Sh SEE ALSO
64.Xr sigaction 2 , 57.Xr sigaction 2 ,
65.Xr exit 2 58.Xr exit 3
66.Sh STANDARDS 59.Sh STANDARDS
67The 60The
68.Fn abort 61.Fn abort
69function 62function conforms to
70conforms to 63.St -p1003.1-90 .
71.St -ansiC .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
index c298e016b4..244e3b28aa 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.15 2007/09/03 14:40:16 millert 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,27 +28,43 @@
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";*/
36static char *rcsid = "$Id: abort.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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"
42 36
43void 37void
44abort() 38abort(void)
45{ 39{
40 struct atexit *p = __atexit;
41 static int cleanup_called = 0;
46 sigset_t mask; 42 sigset_t mask;
47 43
44
48 sigfillset(&mask); 45 sigfillset(&mask);
49 /* 46 /*
50 * don't block SIGABRT to give any handler a chance; we ignore 47 * don't block SIGABRT to give any handler a chance; we ignore
51 * any errors -- X311J doesn't allow abort to return anyway. 48 * any errors -- X311J doesn't allow abort to return anyway.
52 */ 49 */
53 sigdelset(&mask, SIGABRT); 50 sigdelset(&mask, SIGABRT);
54 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 51 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
52
53 /*
54 * POSIX requires we flush stdio buffers on abort
55 */
56 if (cleanup_called == 0) {
57 /* the cleanup routine lives in fns[0] on the last page */
58 while (p != NULL && p->next != NULL)
59 p = p->next;
60 /* the check for fn_dso == NULL is mostly paranoia */
61 if (p != NULL && p->fns[0].fn_dso == NULL &&
62 p->fns[0].fn_ptr.std_func != NULL) {
63 cleanup_called = 1;
64 (*p->fns[0].fn_ptr.std_func)();
65 }
66 }
67
55 (void)kill(getpid(), SIGABRT); 68 (void)kill(getpid(), SIGABRT);
56 69
57 /* 70 /*
@@ -59,7 +72,7 @@ abort()
59 * it again, only harder. 72 * it again, only harder.
60 */ 73 */
61 (void)signal(SIGABRT, SIG_DFL); 74 (void)signal(SIGABRT, SIG_DFL);
62 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); 75 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
63 (void)kill(getpid(), SIGABRT); 76 (void)kill(getpid(), SIGABRT);
64 exit(1); 77 _exit(1);
65} 78}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
index 4748d89e77..c4135f9c84 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,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: @(#)abs.3 6.4 (Berkeley) 6/29/91 32.\" $OpenBSD: abs.3,v 1.8 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ABS 3 35.Dt ABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,21 +44,18 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn abs 46.Fn abs
52function 47function computes the absolute value of the integer
53computes 48.Fa j .
54the absolute value of the integer
55.Ar j .
56.Sh RETURN VALUES 49.Sh RETURN VALUES
57The 50The
58.Fn abs 51.Fn abs
59function 52function returns the absolute value.
60returns
61the absolute value.
62.Sh SEE ALSO 53.Sh SEE ALSO
63.Xr floor 3 ,
64.Xr labs 3 ,
65.Xr cabs 3 , 54.Xr cabs 3 ,
55.Xr floor 3 ,
66.Xr hypot 3 , 56.Xr hypot 3 ,
57.Xr imaxabs 3 ,
58.Xr labs 3 ,
67.Xr math 3 59.Xr math 3
68.Sh STANDARDS 60.Sh STANDARDS
69The 61The
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";*/
36static char *rcsid = "$Id: abs.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41int 33int
42abs(j) 34abs(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..d7fddb04c2 100644
--- a/src/lib/libc/stdlib/alloca.3
+++ b/src/lib/libc/stdlib/alloca.3
@@ -9,11 +9,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 12.\" 3. Neither the name of the University nor the names of its contributors
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software 13.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 14.\" without specific prior written permission.
19.\" 15.\"
@@ -29,12 +25,11 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 26.\" SUCH DAMAGE.
31.\" 27.\"
32.\" from: @(#)alloca.3 5.1 (Berkeley) 5/2/91 28.\" $OpenBSD: alloca.3,v 1.11 2007/05/31 19:19:31 jmc 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: May 31 2007 $
36.Dt ALLOCA 3 31.Dt ALLOCA 3
37.Os BSD 4 32.Os
38.Sh NAME 33.Sh NAME
39.Nm alloca 34.Nm alloca
40.Nd memory allocator 35.Nd memory allocator
@@ -45,35 +40,41 @@
45.Sh DESCRIPTION 40.Sh DESCRIPTION
46The 41The
47.Fn alloca 42.Fn alloca
48function 43function allocates
49allocates
50.Fa size 44.Fa size
51bytes of space in the stack frame of the caller. 45bytes of space in the stack frame of the caller.
52This temporary space is automatically freed on 46This temporary space is automatically freed on return.
53return.
54.Sh RETURN VALUES 47.Sh RETURN VALUES
55The 48The
56.Fn alloca 49.Fn alloca
57function returns a pointer to the beginning of the allocated space. 50function returns a pointer to the beginning of the allocated space.
58If the allocation failed, a
59.Dv NULL
60pointer is returned.
61.Sh SEE ALSO 51.Sh SEE ALSO
52.Xr pagesize 1 ,
62.Xr brk 2 , 53.Xr brk 2 ,
63.Xr pagesize 2
64.Xr calloc 3 , 54.Xr calloc 3 ,
65.Xr malloc 3 , 55.Xr malloc 3 ,
66.Xr realloc 3 , 56.Xr realloc 3
67.Sh BUGS 57.Sh BUGS
68The 58The
69.Fn alloca 59.Fn alloca
70function 60function is machine dependent; its use is discouraged.
71is machine dependent; its use is discouraged.
72.\" .Sh HISTORY 61.\" .Sh HISTORY
73.\" The 62.\" The
74.\" .Fn alloca 63.\" .Fn alloca
75.\" function appeared in 64.\" function appeared in
76.\" .Bx ?? . 65.\" .Bx ?? .
77.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd 66.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
78.\" The first man page (or link to a man page that I can find at the 67.\" The first man page (or link to a man page that I can find at the
79.\" moment is 4.3... 68.\" moment is 4.3...
69.Pp
70The
71.Fn alloca
72function is slightly unsafe because it cannot ensure that the pointer
73returned points to a valid and usable block of memory.
74The allocation made may exceed the bounds of the stack, or even go
75further into other objects in memory, and
76.Fn alloca
77cannot determine such an error.
78Avoid
79.Fn alloca
80with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
index 07de054d3c..0615feabb1 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,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: @(#)atexit.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: atexit.3,v 1.8 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ATEXIT 3 35.Dt ATEXIT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,17 +44,22 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn atexit 46.Fn atexit
52function 47function registers the given
53registers the given 48.Fa function
54.Ar function
55to be called at program exit, whether via 49to be called at program exit, whether via
56.Xr exit 3 50.Xr exit 3
57or via return from the program's 51or via return from the program's
58.Em main . 52.Fn main .
59Functions so registered are called in reverse order; 53Functions so registered are called in reverse order;
60no arguments are passed. 54no arguments are passed.
61At least 32 functions can always be registered, 55At least 32 functions can always be registered,
62and more are allowed as long as sufficient memory can be allocated. 56and more are allowed as long as sufficient memory can be allocated.
57.Pp
58.Fn atexit
59is very difficult to use correctly without creating
60.Xr exit 3 Ns -time
61races.
62Unless 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
74The 74The
75.Fn atexit 75.Fn atexit
76function 76function conforms to
77conforms 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..4d28fb5ef6 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -1,68 +1,209 @@
1/*- 1/* $OpenBSD: atexit.c,v 1.14 2007/09/05 20:47:47 chl 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>
39static char *rcsid = "$Id: atexit.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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
40int __atexit_invalid = 1;
45struct atexit *__atexit; 41struct atexit *__atexit;
46 42
47/* 43/*
48 * Register a function to be performed at exit. 44 * Function pointers are stored in a linked list of pages. The list
45 * is initially empty, and pages are allocated on demand. The first
46 * function pointer in the first allocated page (the last one in
47 * the linked list) is reserved for the cleanup function.
48 *
49 * Outside the following functions, all pages are mprotect()'ed
50 * to prevent unintentional/malicious corruption.
51 */
52
53/*
54 * Register a function to be performed at exit or when a shared object
55 * with the given dso handle is unloaded dynamically. Also used as
56 * the backend for atexit(). For more info on this API, see:
57 *
58 * http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor
49 */ 59 */
50int 60int
51atexit(fn) 61__cxa_atexit(void (*func)(void *), void *arg, void *dso)
52 void (*fn)();
53{ 62{
54 static struct atexit __atexit0; /* one guaranteed table */ 63 struct atexit *p = __atexit;
55 register struct atexit *p; 64 struct atexit_fn *fnp;
65 int pgsize = getpagesize();
66 int ret = -1;
56 67
57 if ((p = __atexit) == NULL) 68 if (pgsize < sizeof(*p))
58 __atexit = p = &__atexit0; 69 return (-1);
59 else if (p->ind >= ATEXIT_SIZE) { 70 _ATEXIT_LOCK();
60 if ((p = malloc(sizeof(*p))) == NULL) 71 p = __atexit;
61 return (-1); 72 if (p != NULL) {
62 p->ind = 0; 73 if (p->ind + 1 >= p->max)
74 p = NULL;
75 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
76 goto unlock;
77 }
78 if (p == NULL) {
79 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
80 MAP_ANON | MAP_PRIVATE, -1, 0);
81 if (p == MAP_FAILED)
82 goto unlock;
83 if (__atexit == NULL) {
84 memset(&p->fns[0], 0, sizeof(p->fns[0]));
85 p->ind = 1;
86 } else
87 p->ind = 0;
88 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
89 sizeof(p->fns[0]);
63 p->next = __atexit; 90 p->next = __atexit;
64 __atexit = p; 91 __atexit = p;
92 if (__atexit_invalid)
93 __atexit_invalid = 0;
94 }
95 fnp = &p->fns[p->ind++];
96 fnp->fn_ptr.cxa_func = func;
97 fnp->fn_arg = arg;
98 fnp->fn_dso = dso;
99 if (mprotect(p, pgsize, PROT_READ))
100 goto unlock;
101 ret = 0;
102unlock:
103 _ATEXIT_UNLOCK();
104 return (ret);
105}
106
107/*
108 * Register a function to be performed at exit.
109 */
110int
111atexit(void (*func)(void))
112{
113 return (__cxa_atexit((void (*)(void *))func, NULL, NULL));
114}
115
116/*
117 * Call all handlers registered with __cxa_atexit() for the shared
118 * object owning 'dso'.
119 * Note: if 'dso' is NULL, then all remaining handlers are called.
120 */
121void
122__cxa_finalize(void *dso)
123{
124 struct atexit *p, *q;
125 struct atexit_fn fn;
126 int n, pgsize = getpagesize();
127 static int call_depth;
128
129 if (__atexit_invalid)
130 return;
131
132 call_depth++;
133
134 for (p = __atexit; p != NULL; p = p->next) {
135 for (n = p->ind; --n >= 0;) {
136 if (p->fns[n].fn_ptr.cxa_func == NULL)
137 continue; /* already called */
138 if (dso != NULL && dso != p->fns[n].fn_dso)
139 continue; /* wrong DSO */
140
141 /*
142 * Mark handler as having been already called to avoid
143 * dupes and loops, then call the appropriate function.
144 */
145 fn = p->fns[n];
146 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) {
147 p->fns[n].fn_ptr.cxa_func = NULL;
148 mprotect(p, pgsize, PROT_READ);
149 }
150 if (dso != NULL)
151 (*fn.fn_ptr.cxa_func)(fn.fn_arg);
152 else
153 (*fn.fn_ptr.std_func)();
154 }
155 }
156
157 /*
158 * If called via exit(), unmap the pages since we have now run
159 * all the handlers. We defer this until calldepth == 0 so that
160 * we don't unmap things prematurely if called recursively.
161 */
162 if (dso == NULL && --call_depth == 0) {
163 for (p = __atexit; p != NULL; ) {
164 q = p;
165 p = p->next;
166 munmap(q, pgsize);
167 }
168 __atexit = NULL;
169 }
170}
171
172/*
173 * Register the cleanup function
174 */
175void
176__atexit_register_cleanup(void (*func)(void))
177{
178 struct atexit *p;
179 int pgsize = getpagesize();
180
181 if (pgsize < sizeof(*p))
182 return;
183 _ATEXIT_LOCK();
184 p = __atexit;
185 while (p != NULL && p->next != NULL)
186 p = p->next;
187 if (p == NULL) {
188 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
189 MAP_ANON | MAP_PRIVATE, -1, 0);
190 if (p == MAP_FAILED)
191 goto unlock;
192 p->ind = 1;
193 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
194 sizeof(p->fns[0]);
195 p->next = NULL;
196 __atexit = p;
197 if (__atexit_invalid)
198 __atexit_invalid = 0;
199 } else {
200 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
201 goto unlock;
65 } 202 }
66 p->fns[p->ind++] = fn; 203 p->fns[0].fn_ptr.std_func = func;
67 return (0); 204 p->fns[0].fn_arg = NULL;
205 p->fns[0].fn_dso = NULL;
206 mprotect(p, pgsize, PROT_READ);
207unlock:
208 _ATEXIT_UNLOCK();
68} 209}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
index 8b756e8fe2..1b23565dd0 100644
--- a/src/lib/libc/stdlib/atexit.h
+++ b/src/lib/libc/stdlib/atexit.h
@@ -1,46 +1,51 @@
1/*- 1/* $OpenBSD: atexit.h,v 1.7 2007/09/03 14:40:16 millert Exp $ */
2 * Copyright (c) 1990 The Regents of the University of California. 2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
3 * All rights reserved. 5 * All rights reserved.
4 * 6 *
5 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
7 * are met: 9 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 * 10 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 11 * - Redistributions of source code must retain the above copyright
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12 * notice, this list of conditions and the following disclaimer.
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 13 * - Redistributions in binary form must reproduce the above
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 14 * copyright notice, this list of conditions and the following
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 15 * disclaimer in the documentation and/or other materials provided
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 16 * with the distribution.
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 17 *
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 * SUCH DAMAGE. 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 * 30 *
33 * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90
34 * $Id: atexit.h,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $
35 */ 31 */
36 32
37/* must be at least 32 to guarantee ANSI conformance */
38#define ATEXIT_SIZE 32
39
40struct atexit { 33struct atexit {
41 struct atexit *next; /* next in list */ 34 struct atexit *next; /* next in list */
42 int ind; /* next index in this table */ 35 int ind; /* next index in this table */
43 void (*fns[ATEXIT_SIZE])(); /* the table itself */ 36 int max; /* max entries >= ATEXIT_SIZE */
37 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
47extern int __atexit_invalid;
46extern struct atexit *__atexit; /* points to head of LIFO stack */ 48extern struct atexit *__atexit; /* points to head of LIFO stack */
49
50int __cxa_atexit(void (*)(void *), void *, void *);
51void __cxa_finalize(void *);
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
index 53e04f71c5..2538d0c879 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.5 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ATOF 3 35.Dt ATOF 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -52,9 +47,9 @@ string to double
52The 47The
53.Fn atof 48.Fn atof
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Ar double 52.Li double
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
index 9202de50bb..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";*/
36static char *rcsid = "$Id: atof.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41double 33double
42atof(ascii) 34atof(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..0c6b62b25f 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.9 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ATOI 3 35.Dt ATOI 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -52,13 +47,12 @@ string to integer
52The 47The
53.Fn atoi 48.Fn atoi
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Em nptr 50.Fa nptr
56to 51to
57.Em integer 52.Li integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
61.Pp
62.Bd -literal -offset indent 56.Bd -literal -offset indent
63(int)strtol(nptr, (char **)NULL, 10); 57(int)strtol(nptr, (char **)NULL, 10);
64.Ed 58.Ed
@@ -67,9 +61,26 @@ 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
72The 67The
73.Fn atoi 68.Fn atoi
74function conforms to 69function conforms to
75.St -ansiC . 70.St -ansiC .
71.Sh CAVEATS
72.Nm
73does no overflow checking, handles unsigned numbers poorly,
74and handles strings containing trailing extra characters
75(like
76.Dq "123abc" )
77poorly.
78Careful use of
79.Xr strtol 3
80and
81.Xr strtoul 3
82can alleviate these problems,
83but
84.Xr strtonum 3
85can be used to convert numbers from strings much more safely
86and 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";*/
36static char *rcsid = "$Id: atoi.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41int 33int
42atoi(str) 34atoi(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..3c5551182d 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.7 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt ATOL 3 35.Dt ATOL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -52,9 +47,9 @@ string to long integer
52The 47The
53.Fn atol 48.Fn atol
54function converts the initial portion of the string pointed to by 49function converts the initial portion of the string pointed to by
55.Ar nptr 50.Fa nptr
56to 51to
57.Em long integer 52.Li long integer
58representation. 53representation.
59.Pp 54.Pp
60It is equivalent to: 55It is equivalent to:
@@ -64,12 +59,12 @@ strtol(nptr, (char **)NULL, 10);
64.Sh SEE ALSO 59.Sh SEE ALSO
65.Xr atof 3 , 60.Xr atof 3 ,
66.Xr atoi 3 , 61.Xr atoi 3 ,
62.Xr atoll 3 ,
67.Xr strtod 3 , 63.Xr strtod 3 ,
68.Xr strtol 3 , 64.Xr strtol 3 ,
69.Xr strtoul 3 65.Xr strtoul 3
70.Sh STANDARDS 66.Sh STANDARDS
71The 67The
72.Fn atol 68.Fn atol
73function 69function conforms to
74conforms to 70.St -ansiC-99 .
75.St -ansiC .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
index 31ed06298b..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";*/
36static char *rcsid = "$Id: atol.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41long 33long
42atol(str) 34atol(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/calloc.3 b/src/lib/libc/stdlib/atoll.3
index d0754b46a0..608a61f4ce 100644
--- a/src/lib/libc/stdlib/calloc.3
+++ b/src/lib/libc/stdlib/atoll.3
@@ -1,4 +1,4 @@
1.\" Copyright (c) 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved. 2.\" All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,39 +29,42 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)calloc.3 5.2 (Berkeley) 6/29/91 32.\" $OpenBSD: atoll.3,v 1.5 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt CALLOC 3 35.Dt ATOLL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm calloc 38.Nm atoll
44.Nd allocate clean memory (zero initialized space) 39.Nd convert
40.Tn ASCII
41string to long long integer
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
47.Ft void * 44.Ft long long
48.Fn calloc "size_t nmemb" "size_t size" 45.Fn atoll "const char *nptr"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn calloc 48.Fn atoll
52function allocates space for an array of 49function converts the initial portion of the string pointed to by
53.Fa nmemb 50.Fa nptr
54objects, each of whose size is 51to
55.Fa size . 52.Li long long integer
56The space is initialized to all bits zero. 53representation.
57.Sh RETURN VALUES 54.Pp
58The 55It is equivalent to:
59.Fn calloc 56.Bd -literal -offset indent
60function returns 57strtoll(nptr, (char **)NULL, 10);
61a pointer to the 58.Ed
62the allocated space if successful; otherwise a null pointer is returned.
63.Sh SEE ALSO 59.Sh SEE ALSO
64.Xr malloc 3 , 60.Xr atof 3 ,
65.Xr realloc 3 , 61.Xr atoi 3 ,
66.Xr free 3 62.Xr atol 3 ,
63.Xr strtod 3 ,
64.Xr strtol 3 ,
65.Xr strtoul 3
67.Sh STANDARDS 66.Sh STANDARDS
68The 67The
69.Fn calloc 68.Fn atoll
70function conforms to 69function conforms to
71.St -ansiC . 70.St -ansiC-99 .
diff --git a/src/lib/libc/string/__strerror.c b/src/lib/libc/stdlib/atoll.c
index cd604906db..a65e682cfb 100644
--- a/src/lib/libc/string/__strerror.c
+++ b/src/lib/libc/stdlib/atoll.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: atoll.c,v 1.3 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,62 +28,11 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <stdlib.h>
35/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/
36static char *rcsid = "$Id: __strerror.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38 32
39#ifdef NLS 33long long
40#define catclose _catclose 34atoll(str)
41#define catgets _catgets 35 const char *str;
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
58char *
59__strerror(num, buf)
60 int num;
61 char *buf;
62{ 36{
63#define UPREFIX "Unknown error: %u" 37 return(strtoll(str, (char **)NULL, 10));
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} 38}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
index 1622c96c6b..4877a1023e 100644
--- a/src/lib/libc/stdlib/bsearch.3
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -1,5 +1,5 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California. 1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" All rights reserved. 2.\" The Regents of the University of California. All rights reserved.
3.\" 3.\"
4.\" This code is derived from software contributed to Berkeley by 4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information 5.\" the American National Standards Committee X3, on Information
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,10 +29,9 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)bsearch.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: bsearch.3,v 1.7 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt BSEARCH 3 35.Dt BSEARCH 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -51,12 +46,12 @@ The
51.Fn bsearch 46.Fn bsearch
52function searches an array of 47function searches an array of
53.Fa nmemb 48.Fa nmemb
54objects, the initial member of which is 49objects, the initial member of which is
55pointed to by 50pointed to by
56.Fa base , 51.Fa base ,
57for a member that matches the object pointed to by 52for a member that matches the object pointed to by
58.Fa key . 53.Fa key .
59The size of each member of the array is specified by 54The size of each member of the array is specified by
60.Fa size . 55.Fa size .
61.Pp 56.Pp
62The contents of the array should be in ascending sorted order according 57The contents of the array should be in ascending sorted order according
@@ -64,9 +59,7 @@ to the comparison function referenced by
64.Fa compar . 59.Fa compar .
65The 60The
66.Fa compar 61.Fa compar
67routine 62routine is expected to have two arguments which point to the
68is expected to have two
69two arguments which point to the
70.Fa key 63.Fa key
71object and to an array member, in that order, and should return an integer 64object and to an array member, in that order, and should return an integer
72less than, equal to, or greater than zero if the 65less than, equal to, or greater than zero if the
@@ -83,7 +76,7 @@ If two members compare as equal, which member is matched is unspecified.
83.Xr db 3 , 76.Xr db 3 ,
84.Xr lsearch 3 , 77.Xr lsearch 3 ,
85.Xr qsort 3 , 78.Xr qsort 3 ,
86.\" .Xr tsearch 3 79.Xr tsearch 3
87.Sh STANDARDS 80.Sh STANDARDS
88The 81The
89.Fn bsearch 82.Fn bsearch
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
index fac03f694f..8193d27c60 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";*/
36static char *rcsid = "$Id: bsearch.c,v 1.1.1.1 1995/10/18 08:42:16 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 30#include <stdlib.h>
40 31
41/* 32/*
@@ -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 */
57void * 48void *
58bsearch(key, base0, nmemb, size, compar) 49bsearch(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..373c7ff75d
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: cfree.c,v 1.5 2005/08/08 08:05:36 espie 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 <sys/cdefs.h>
29#include <stdlib.h>
30
31#ifdef __indr_reference
32__indr_reference(free, cfree);
33#else
34
35void
36cfree(void *p)
37{
38 free(p);
39}
40#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
index a4730694a5..4a48ab1ea4 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,10 +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.\" from: @(#)div.3 5.2 (Berkeley) 4/19/91 30.\" $OpenBSD: div.3,v 1.9 2007/05/31 19:19:31 jmc Exp $
35.\" $Id: div.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd $Mdocdate: May 31 2007 $
38.Dt DIV 3 33.Dt DIV 3
39.Os 34.Os
40.Sh NAME 35.Sh NAME
@@ -47,24 +42,24 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn div 44.Fn div
50function 45function computes the value
51computes the value 46.Fa num Ns / Ns Fa denom
52.Fa num/denom
53and returns the quotient and remainder in a structure named 47and returns the quotient and remainder in a structure named
54.Fa div_t 48.Fa div_t
55that contains two 49that contains two
56.Em int 50.Li int
57members named 51members named
58.Fa quot 52.Fa quot
59and 53and
60.Fa rem . 54.Fa rem .
61.Sh SEE ALSO 55.Sh SEE ALSO
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 math 3 ,
60.Xr qdiv 3
65.Sh STANDARDS 61.Sh STANDARDS
66The 62The
67.Fn div 63.Fn div
68function 64function conforms to
69conforms to
70.St -ansiC . 65.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";*/
39static char *rcsid = "$Id: div.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <stdlib.h> /* div_t */ 34#include <stdlib.h> /* div_t */
43 35
44div_t 36div_t
45div(num, denom) 37div(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..0717a2c02a
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: ecvt.3,v 1.8 2007/05/31 19:19:31 jmc Exp $
2.\"
3.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.\" Sponsored in part by the Defense Advanced Research Projects
18.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
19.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
20.\"
21.Dd $Mdocdate: May 31 2007 $
22.Dt ECVT 3
23.Os
24.Sh NAME
25.Nm ecvt ,
26.Nm fcvt ,
27.Nm gcvt
28.Nd convert double to
29.Tn ASCII
30string
31.Sh SYNOPSIS
32.Fd #include <stdlib.h>
33.Ft char *
34.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
35.Ft char *
36.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
37.Ft char *
38.Fn gcvt "double value" "int ndigit" "char *buf"
39.Sh DESCRIPTION
40.Bf -symbolic
41These functions are provided for compatibility with legacy code.
42New code should use the
43.Xr snprintf 3
44function for improved safety and portability.
45.Ef
46.Pp
47The
48.Fn ecvt ,
49.Fn fcvt
50and
51.Fn gcvt
52functions convert the double precision floating-point number
53.Fa value
54to a NUL-terminated
55.Tn ASCII
56string.
57.Pp
58The
59.Fn ecvt
60function converts
61.Fa value
62to a NUL-terminated string of exactly
63.Fa ndigit
64digits and returns a pointer to that string.
65The result is padded with zeroes from left to right as needed.
66There are no leading zeroes unless
67.Fa value
68itself is 0.
69The least significant digit is rounded in an implementation-dependent manner.
70The position of the decimal point relative to the beginning of the string
71is stored in
72.Fa decpt .
73A negative value indicates that the decimal point is located
74to the left of the returned digits (this occurs when there is no
75whole number component to
76.Fa value ) .
77If
78.Fa value
79is zero, it is unspecified whether the integer pointed to by
80.Fa decpt
81will be 0 or 1.
82The decimal point itself is not included in the returned string.
83If the sign of the result is negative, the integer pointed to by
84.Fa sign
85is non-zero; otherwise, it is 0.
86.Pp
87If the converted value is out of range or is not representable,
88the contents of the returned string are unspecified.
89.Pp
90The
91.Fn fcvt
92function is identical to
93.Fn ecvt
94with the exception that
95.Fa ndigit
96specifies the number of digits after the decimal point (zero-padded as
97needed).
98.Pp
99The
100.Fn gcvt
101function converts
102.Fa value
103to a NUL-terminated string similar to the %g
104.Xr printf 3
105format specifier and stores the result in
106.Fa buf .
107It produces
108.Fa ndigit
109significant digits similar to the %f
110.Xr printf 3
111format specifier where possible.
112If
113.Fa ndigit
114does allow sufficient precision, the result is stored in
115exponential notation similar to the %e
116.Xr printf 3
117format specifier.
118If
119.Fa value
120is less than zero,
121.Fa buf
122will be prefixed with a minus sign.
123A decimal point is included in the returned string if
124.Fa value
125is not a whole number.
126Unlike the
127.Fn ecvt
128and
129.Fn fcvt
130functions,
131.Fa buf
132is not zero-padded.
133.Sh RETURN VALUES
134The
135.Fn ecvt ,
136.Fn fcvt
137and
138.Fn gcvt
139functions return a NUL-terminated string representation of
140.Fa value .
141.Sh WARNINGS
142The
143.Fn ecvt
144and
145.Fn fcvt
146functions return a pointer to internal storage space that will be
147overwritten by subsequent calls to either function.
148.Pp
149The maximum possible precision of the return value is limited by the
150precision of a double and may not be the same on all architectures.
151.Pp
152The
153.Xr snprintf 3
154function is preferred over these functions for new code.
155.Sh SEE ALSO
156.Xr printf 3 ,
157.Xr strtod 3
158.Sh STANDARDS
159The
160.Fn ecvt ,
161.Fn fcvt
162and
163.Fn gcvt
164functions conform to
165.St -p1003.1-2001 .
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c
new file mode 100644
index 0000000000..719370a8f3
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,105 @@
1/* $OpenBSD: ecvt.c,v 1.6 2006/10/29 18:45:56 deraadt 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
27extern char *__dtoa(double, int, int, int *, int *, char **);
28extern void __freedtoa(char *);
29static char *__cvt(double, int, int *, int *, int, int);
30
31static char *
32__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
33{
34 static char *s;
35 char *p, *rve, c;
36 size_t siz;
37
38 if (ndigit == 0) {
39 *sign = value < 0.0;
40 *decpt = 0;
41 return ("");
42 }
43
44 if (s) {
45 free(s);
46 s = NULL;
47 }
48
49 if (ndigit < 0)
50 siz = -ndigit + 1;
51 else
52 siz = ndigit + 1;
53
54
55 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
56 if (value == 0.0) {
57 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
58 *sign = 0;
59 if ((rve = s = (char *)malloc(siz)) == NULL)
60 return(NULL);
61 *rve++ = '0';
62 *rve = '\0';
63 } else {
64 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
65 if (*decpt == 9999) {
66 /* Infinity or Nan, convert to inf or nan like printf */
67 *decpt = 0;
68 c = *p;
69 __freedtoa(p);
70 return(c == 'I' ? "inf" : "nan");
71 }
72 /* Make a local copy and adjust rve to be in terms of s */
73 if (pad && fmode)
74 siz += *decpt;
75 if ((s = (char *)malloc(siz)) == NULL) {
76 __freedtoa(p);
77 return(NULL);
78 }
79 (void) strlcpy(s, p, siz);
80 rve = s + (rve - p);
81 __freedtoa(p);
82 }
83
84 /* Add trailing zeros */
85 if (pad) {
86 siz -= rve - s;
87 while (--siz)
88 *rve++ = '0';
89 *rve = '\0';
90 }
91
92 return(s);
93}
94
95char *
96ecvt(double value, int ndigit, int *decpt, int *sign)
97{
98 return(__cvt(value, ndigit, decpt, sign, 0, 1));
99}
100
101char *
102fcvt(double value, int ndigit, int *decpt, int *sign)
103{
104 return(__cvt(value, ndigit, decpt, sign, 1, 1));
105}
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..45eae80a08 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,25 +29,30 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)exit.3 6.6 (Berkeley) 6/29/91 32.\" $OpenBSD: exit.3,v 1.11 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt EXIT 3 35.Dt EXIT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm exit 38.Nm exit, _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.Fd #include <stdlib.h>
47.Ft void 42.Ft void
48.Fn exit "int status" 43.Fn exit "int status"
44.Ft void
45.Fn _Exit "int status"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50.Fn Exit 47The
51terminates a process. 48.Fn exit
49and
50.Fn _Exit
51functions terminate a process.
52.Pp 52.Pp
53Before termination it performs the following functions in the 53Before termination,
54order listed: 54.Fn exit
55performs the following operations in the order listed:
55.Bl -enum -offset indent 56.Bl -enum -offset indent
56.It 57.It
57Call the functions registered with the 58Call the functions registered with the
@@ -66,19 +67,48 @@ Unlink all files created with the
66.Xr tmpfile 3 67.Xr tmpfile 3
67function. 68function.
68.El 69.El
70.Pp
71The
72.Fn _Exit
73function terminates without calling the functions registered with the
74.Xr atexit 3
75function.
76The
77.Ox
78implementation of
79.Fn _Exit
80does not flush open output streams or unlink files created with the
81.Xr tmpfile 3
82function.
83However, this behavior is implementation-specific.
84.Pp
85Lastly,
86.Fn exit
87and
88.Fn _Exit
89call
90.Xr _exit 2 .
91Note that typically
92.Xr _exit 2
93only passes the lower 8 bits of
94.Fa status
95on to the parent, thus negative values have less meaning.
69.Sh RETURN VALUES 96.Sh RETURN VALUES
70The 97The
71.Fn exit 98.Fn exit
72function 99and
73never returns. 100.Fn _Exit
101functions never return.
74.Sh SEE ALSO 102.Sh SEE ALSO
75.Xr _exit 2 , 103.Xr _exit 2 ,
76.Xr atexit 3 , 104.Xr atexit 3 ,
77.Xr intro 3 , 105.Xr intro 3 ,
106.Xr sysexits 3 ,
78.Xr tmpfile 3 107.Xr tmpfile 3
79.Sh STANDARDS 108.Sh STANDARDS
80The 109The
81.Fn exit 110.Fn exit
82function 111and
83conforms to 112.Fn _Exit
84.St -ansiC . 113functions conform to
114.St -ansiC-99 .
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>
36static char *rcsid = "$Id: exit.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
43void (*__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 */
45int __isthreaded = 0;
44 46
45/* 47/*
46 * Exit, flushing stdio buffers if necessary. 48 * Exit, flushing stdio buffers if necessary.
47 */ 49 */
48void 50void
49exit(status) 51exit(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/free.3 b/src/lib/libc/stdlib/free.3
deleted file mode 100644
index 3d0131d7de..0000000000
--- a/src/lib/libc/stdlib/free.3
+++ /dev/null
@@ -1,82 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission.
23.\"
24.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE.
35.\"
36.\" from: @(#)free.3 5.2 (Berkeley) 6/29/91
37.\" $Id: free.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\"
39.Dd June 29, 1991
40.Dt FREE 3
41.Os
42.Sh NAME
43.Nm free
44.Nd free up memory allocated with malloc, calloc or realloc
45.Sh SYNOPSIS
46.Fd #include <stdlib.h>
47.Ft void
48.Fn free "void *ptr"
49.Sh DESCRIPTION
50The
51.Fn free
52function causes the space pointed to by
53.Fa ptr
54to be deallocated, that is, made available
55for further allocation.
56If
57.Fa ptr
58is a null pointer, no action occurs.
59Otherwise, if the argument does not match a pointer earlier
60returned by the
61.Xr calloc ,
62.Xr malloc ,
63or
64.Xr realloc
65function, or if the space has been deallocated by a call to
66.Fn free
67or
68.Xr realloc ,
69general havoc may occur.
70.Sh RETURN VALUES
71The
72.Fn free
73function returns no value.
74.Sh SEE ALSO
75.Xr calloc 3 ,
76.Xr malloc 3 ,
77.Xr realloc 3
78.Sh STANDARDS
79The
80.Fn free
81function conforms to
82.St -ansiC .
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..c24157e465
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,111 @@
1/* $OpenBSD: gcvt.c,v 1.10 2006/10/29 18:45:56 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003, 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 <locale.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28extern char *__dtoa(double, int, int, int *, int *, char **);
29extern void __freedtoa(char *);
30
31char *
32gcvt(double value, int ndigit, char *buf)
33{
34 char *digits, *dst, *src;
35 int i, decpt, sign;
36 struct lconv *lconv;
37
38 lconv = localeconv();
39 if (ndigit == 0) {
40 buf[0] = '\0';
41 return (buf);
42 }
43
44 digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
45 if (decpt == 9999) {
46 /*
47 * Infinity or NaN, convert to inf or nan with sign.
48 * We assume the buffer is at least ndigit long.
49 */
50 snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "",
51 *digits == 'I' ? "inf" : "nan");
52 __freedtoa(digits);
53 return (buf);
54 }
55
56 dst = buf;
57 if (sign)
58 *dst++ = '-';
59
60 if (decpt < 0 || decpt > ndigit) {
61 /* exponential format (e.g. 1.2345e+13) */
62 if (--decpt < 0) {
63 sign = 1;
64 decpt = -decpt;
65 } else
66 sign = 0;
67 src = digits;
68 *dst++ = *src++;
69 *dst++ = *lconv->decimal_point;
70 while (*src != '\0')
71 *dst++ = *src++;
72 *dst++ = 'e';
73 if (sign)
74 *dst++ = '-';
75 else
76 *dst++ = '+';
77 if (decpt < 10) {
78 *dst++ = '0';
79 *dst++ = '0' + decpt;
80 *dst = '\0';
81 } else {
82 /* XXX - optimize */
83 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
84 continue;
85 dst[i + 1] = '\0';
86 while (decpt != 0) {
87 dst[i--] = '0' + decpt % 10;
88 decpt /= 10;
89 }
90 }
91 } else {
92 /* standard format */
93 for (i = 0, src = digits; i < decpt; i++) {
94 if (*src != '\0')
95 *dst++ = *src++;
96 else
97 *dst++ = '0';
98 }
99 if (*src != '\0') {
100 if (src == digits)
101 *dst++ = '0'; /* zero before decimal point */
102 *dst++ = *lconv->decimal_point;
103 for (i = decpt; digits[i] != '\0'; i++) {
104 *dst++ = digits[i];
105 }
106 }
107 *dst = '\0';
108 }
109 __freedtoa(digits);
110 return (buf);
111}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
index 411eb35da4..1d8546997f 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.12 2007/05/31 19:19:31 jmc Exp $
37.\" $Id: getenv.3,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt GETENV 3 35.Dt GETENV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -56,59 +51,51 @@
56.Ft void 51.Ft void
57.Fn unsetenv "const char *name" 52.Fn unsetenv "const char *name"
58.Sh DESCRIPTION 53.Sh DESCRIPTION
59These functions set, unset and fetch environment variables from the 54These functions set, unset, and fetch environment variables from the host
60host
61.Em environment list . 55.Em environment list .
62For compatibility with differing environment conventions, 56For compatibility with differing environment conventions, the given arguments
63the given arguments 57.Fa name
64.Ar name
65and 58and
66.Ar value 59.Fa value
67may be appended and prepended, 60may be appended and prepended, respectively, with an equal sign
68respectively,
69with an equal sign
70.Dq Li \&= . 61.Dq Li \&= .
71.Pp 62.Pp
72The 63The
73.Fn getenv 64.Fn getenv
74function obtains the current value of the environment variable, 65function obtains the current value of the environment variable
75.Ar name . 66.Fa name .
76If the variable 67If the variable
77.Ar name 68.Fa name
78is not in the current environment , 69is not in the current environment, a null pointer is returned.
79a null pointer is returned.
80.Pp 70.Pp
81The 71The
82.Fn setenv 72.Fn setenv
83function inserts or resets the environment variable 73function inserts or resets the environment variable
84.Ar name 74.Fa name
85in the current environment list. 75in the current environment list.
86If the variable 76If the variable
87.Ar name 77.Fa name
88does not exist in the list, 78does not exist in the list, it is inserted with the given
89it is inserted with the given 79.Fa value .
90.Ar value.
91If the variable does exist, the argument 80If the variable does exist, the argument
92.Ar overwrite 81.Fa overwrite
93is tested; if 82is tested; if
94.Ar overwrite is 83.Fa overwrite
95zero, the 84is zero, the variable is not reset, otherwise it is reset to the given
96variable is not reset, otherwise it is reset 85.Fa value .
97to the given
98.Ar value .
99.Pp 86.Pp
100The 87The
101.Fn putenv 88.Fn putenv
102function takes an argument of the form ``name=value'' and is 89function takes an argument of the form
103equivalent to: 90.Ar name Ns = Ns Ar value
91and is equivalent to:
104.Bd -literal -offset indent 92.Bd -literal -offset indent
105setenv(name, value, 1); 93setenv(name, value, 1);
106.Ed 94.Ed
107.Pp 95.Pp
108The 96The
109.Fn unsetenv 97.Fn unsetenv
110function 98function deletes all instances of the variable name pointed to by
111deletes all instances of the variable name pointed to by
112.Fa name 99.Fa name
113from the list. 100from the list.
114.Sh RETURN VALUES 101.Sh RETURN VALUES
@@ -118,8 +105,11 @@ and
118.Fn putenv 105.Fn putenv
119return zero if successful; otherwise the global variable 106return zero if successful; otherwise the global variable
120.Va errno 107.Va errno
121is set to indicate the error and a 108is set to indicate the error and \-1 is returned.
122\-1 is returned. 109.Pp
110If
111.Fn getenv
112is successful, the string returned should be considered read-only.
123.Sh ERRORS 113.Sh ERRORS
124.Bl -tag -width Er 114.Bl -tag -width Er
125.It Bq Er ENOMEM 115.It Bq Er ENOMEM
@@ -140,12 +130,18 @@ The
140function conforms to 130function conforms to
141.St -ansiC . 131.St -ansiC .
142.Sh HISTORY 132.Sh HISTORY
133The function
134.Fn getenv
135appeared in
136.At v7
137and
138.Bx 3 .
143The functions 139The functions
144.Fn setenv 140.Fn setenv
145and 141and
146.Fn unsetenv 142.Fn unsetenv
147appeared in 143appeared in
148.At v7 . 144.Bx 4.3 Tahoe .
149The 145The
150.Fn putenv 146.Fn putenv
151function appeared in 147function appeared in
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 09d47f2149..72367b34e2 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.8 2005/08/08 08:05:36 espie 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,27 +28,10 @@
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";*/
36static char *rcsid = "$Id: getenv.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
42/* 34char *__findenv(const char *name, int *offset);
43 * getenv --
44 * Returns ptr to value associated with name, if any, else NULL.
45 */
46char *
47getenv(name)
48 const char *name;
49{
50 int offset;
51 char *__findenv();
52
53 return(__findenv(name, &offset));
54}
55 35
56/* 36/*
57 * __findenv -- 37 * __findenv --
@@ -63,20 +43,38 @@ getenv(name)
63 * This routine *should* be a static; don't use it. 43 * This routine *should* be a static; don't use it.
64 */ 44 */
65char * 45char *
66__findenv(name, offset) 46__findenv(const char *name, int *offset)
67 register char *name;
68 int *offset;
69{ 47{
70 extern char **environ; 48 extern char **environ;
71 register int len; 49 int len, i;
72 register char **P, *C; 50 const char *np;
51 char **p, *cp;
52
53 if (name == NULL || environ == NULL)
54 return (NULL);
55 for (np = name; *np && *np != '='; ++np)
56 ;
57 len = np - name;
58 for (p = environ; (cp = *p) != NULL; ++p) {
59 for (np = name, i = len; i && *cp; i--)
60 if (*cp++ != *np++)
61 break;
62 if (i == 0 && *cp++ == '=') {
63 *offset = p - environ;
64 return (cp);
65 }
66 }
67 return (NULL);
68}
69
70/*
71 * getenv --
72 * Returns ptr to value associated with name, if any, else NULL.
73 */
74char *
75getenv(const char *name)
76{
77 int offset;
73 78
74 for (C = name, len = 0; *C && *C != '='; ++C, ++len); 79 return (__findenv(name, &offset));
75 for (P = environ; *P; ++P)
76 if (!strncmp(*P, name, len))
77 if (*(C = *P + len) == '=') {
78 *offset = P - environ;
79 return(++C);
80 }
81 return(NULL);
82} 80}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
index f843881afd..06167cb7d6 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.40 2007/05/31 19:19:31 jmc Exp $
33.\" 29.\"
34.Dd April 19, 1994 30.Dd $Mdocdate: May 31 2007 $
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.Fd #include <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,23 @@ if it has been specified in the string of accepted option characters,
61.Pp 57.Pp
62The option string 58The option string
63.Fa optstring 59.Fa optstring
64may contain the following elements: individual characters, and 60may contain the following elements: individual characters,
65characters followed by a colon to indicate an option argument 61characters followed by a colon, and characters followed by two colons.
66is to follow. 62A character followed by a single colon indicates that an argument
63is to follow the option on the command line.
64Two colons indicates that the argument is optional \- this is an
65extension not covered by POSIX.
67For example, an option string 66For example, an option string
68.Li "\&""x"" 67.Qq x
69recognizes an option 68recognizes an option
70.Dq Fl x , 69.Fl x ,
71and an option string 70and an option string
72.Li "\&""x:"" 71.Qq Li x:
73recognizes an option and argument 72recognizes an option and argument
74.Dq Fl x Ar argument . 73.Fl x Ar argument .
75It does not matter to 74It does not matter to
76.Fn getopt 75.Fn getopt
77if a following argument has leading white space. 76if a following argument has leading whitespace.
78.Pp 77.Pp
79On return from 78On return from
80.Fn getopt , 79.Fn getopt ,
@@ -87,23 +86,23 @@ contains the index to the next
87argument for a subsequent call 86argument for a subsequent call
88to 87to
89.Fn getopt . 88.Fn getopt .
90The variable
91.Va optopt
92saves the last
93.Em known
94option character returned by
95.Fn getopt .
96.Pp 89.Pp
97The variable 90The variables
98.Va opterr 91.Va opterr
99and 92and
100.Va optind 93.Va optind
101are both initialized to 1. 94are both initialized to 1.
102The 95The
103.Va optind 96.Va optind
104variable may be set to another value before a set of calls to 97variable may be set to another value larger than 0 before a set of calls to
105.Fn getopt 98.Fn getopt
106in order to skip over more or less argv entries. 99in order to skip over more or less
100.Fa argv
101entries.
102An
103.Va optind
104value of 0 is reserved for compatibility with GNU
105.Fn getopt .
107.Pp 106.Pp
108In order to use 107In order to use
109.Fn getopt 108.Fn getopt
@@ -119,101 +118,163 @@ must be reinitialized.
119.Pp 118.Pp
120The 119The
121.Fn getopt 120.Fn getopt
122function 121function returns \-1 when the argument list is exhausted.
123returns \-1
124when the argument list is exhausted, or a non-recognized
125option is encountered.
126The interpretation of options in the argument list may be cancelled 122The interpretation of options in the argument list may be cancelled
127by the option 123by the option
128.Ql -- 124.Ql --
129(double dash) which causes 125(double dash) which causes
130.Fn getopt 126.Fn getopt
131to signal the end of argument processing and returns \-1. 127to signal the end of argument processing and return \-1.
132When all options have been processed (i.e., up to the first non-option 128When all options have been processed (i.e., up to the first non-option
133argument), 129argument),
134.Fn getopt 130.Fn getopt
135returns \-1. 131returns \-1.
136.Sh DIAGNOSTICS 132.Sh RETURN VALUES
137If the 133The
138.Fn getopt 134.Fn getopt
139function encounters a character not found in the string 135function returns the next known option character in
140.Va optarg 136.Fa optstring .
141or detects
142a missing option argument it writes an error message and returns
143.Ql ?
144to the
145.Em stderr .
146Setting
147.Va opterr
148to a zero will disable these error messages.
149If 137If
150.Va optstring 138.Fn getopt
151has a leading 139encounters a character not found in
152.Ql \&: 140.Fa optstring
153then a missing option argument causes a 141or if it detects a missing option argument,
154.Ql \&: 142it returns
155to be returned in addition to suppressing any error messages. 143.Sq \&?
156.Pp 144(question mark).
157Option arguments are allowed to begin with 145If
158.Dq Li \- ; 146.Fa optstring
159this is reasonable but 147has a leading
160reduces the amount of error checking possible. 148.Sq \&:
161.Sh EXTENSIONS 149then a missing option argument causes
150.Sq \&:
151to be returned instead of
152.Sq \&? .
153In either case, the variable
154.Va optopt
155is set to the character that caused the error.
162The 156The
163.Va optreset
164variable was added to make it possible to call the
165.Fn getopt 157.Fn getopt
166function multiple times. 158function returns \-1 when the argument list is exhausted.
167This is an extension to the 159.Sh ENVIRONMENT
168.St -p1003.2 160.Bl -tag -width POSIXLY_CORRECTXX
169specification. 161.It Ev POSIXLY_CORRECT
170.Sh EXAMPLE 162If set, a leading
171.Bd -literal -compact 163.Sq -
172extern char *optarg; 164in
173extern int optind; 165.Ar optstring
166is ignored.
167.El
168.Sh EXAMPLES
169The following code accepts the options
170.Fl b
171and
172.Fl f Ar argument
173and adjusts
174.Va argc
175and
176.Va argv
177after option argument processing has completed.
178.Bd -literal -offset indent
174int bflag, ch, fd; 179int bflag, ch, fd;
175 180
176bflag = 0; 181bflag = 0;
177while ((ch = getopt(argc, argv, "bf:")) != -1) 182while ((ch = getopt(argc, argv, "bf:")) != -1) {
178 switch(ch) { 183 switch (ch) {
179 case 'b': 184 case 'b':
180 bflag = 1; 185 bflag = 1;
181 break; 186 break;
182 case 'f': 187 case 'f':
183 if ((fd = open(optarg, O_RDONLY, 0)) < 0) { 188 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
184 (void)fprintf(stderr, 189 err(1, "%s", optarg);
185 "myname: %s: %s\en", optarg, strerror(errno));
186 exit(1);
187 }
188 break; 190 break;
189 case '?':
190 default: 191 default:
191 usage(); 192 usage();
193 /* NOTREACHED */
194 }
192} 195}
193argc -= optind; 196argc -= optind;
194argv += optind; 197argv += optind;
195.Ed 198.Ed
196.Sh HISTORY 199.Sh DIAGNOSTICS
200If the
201.Fn getopt
202function encounters a character not found in the string
203.Fa optstring
204or detects
205a missing option argument, it writes an error message to
206.Em stderr
207and returns
208.Ql \&? .
209Setting
210.Va opterr
211to a zero will disable these error messages.
212If
213.Fa optstring
214has a leading
215.Ql \&:
216then a missing option argument causes a
217.Ql \&:
218to be returned in addition to suppressing any error messages.
219.Pp
220Option arguments are allowed to begin with
221.Ql - ;
222this is reasonable but reduces the amount of error checking possible.
223.Sh SEE ALSO
224.Xr getopt 1 ,
225.Xr getopt_long 3 ,
226.Xr getsubopt 3
227.Sh STANDARDS
197The 228The
198.Fn getopt 229.Fn getopt
199function appeared 230function implements a superset of the functionality specified by
200.Bx 4.3 . 231.St -p1003.1 .
201.Sh BUGS 232.Pp
233The following extensions are supported:
234.Bl -tag -width "xxx"
235.It Li o
202The 236The
237.Va optreset
238variable was added to make it possible to call the
203.Fn getopt 239.Fn getopt
204function was once specified to return 240function multiple times.
205.Dv EOF 241.It Li o
206instead of \-1. 242If the
207This was changed by 243.Va optind
208.St -p1003.2-92 244variable is set to 0,
209to decouple
210.Fn getopt 245.Fn getopt
211from 246will behave as if the
212.Pa <stdio.h> . 247.Va optreset
213.Pp 248variable has been set.
249This is for compatibility with
250.Tn GNU
251.Fn getopt .
252New code should use
253.Va optreset
254instead.
255.It Li o
256If the first character of
257.Fa optstring
258is a plus sign
259.Pq Ql + ,
260it will be ignored.
261This is for compatibility with
262.Tn GNU
263.Fn getopt .
264.It Li o
265If the first character of
266.Fa optstring
267is a dash
268.Pq Ql - ,
269non-options will be returned as arguments to the option character
270.Ql \e1 .
271This is for compatibility with
272.Tn GNU
273.Fn getopt .
274.It Li o
214A single dash 275A single dash
215.Dq Li - 276.Pq Ql -
216may be specified as an character in 277may be specified as a character in
217.Fa optstring , 278.Fa optstring ,
218however it should 279however it should
219.Em never 280.Em never
@@ -221,40 +282,90 @@ have an argument associated with it.
221This allows 282This allows
222.Fn getopt 283.Fn getopt
223to be used with programs that expect 284to be used with programs that expect
224.Dq Li - 285.Ql -
225as an option flag. 286as an option flag.
226This practice is wrong, and should not be used in any current development. 287This practice is wrong, and should not be used in any current development.
227It is provided for backward compatibility 288It is provided for backward compatibility
228.Em only . 289.Em only .
290Care should be taken not to use
291.Ql -
292as the first character in
293.Fa optstring
294to avoid a semantic conflict with
295.Tn GNU
296.Fn getopt
297semantics (see above).
229By default, a single dash causes 298By default, a single dash causes
230.Fn getopt 299.Fn getopt
231to return \-1. 300to return \-1.
232This is, we believe, compatible with System V. 301.El
302.Pp
303Historic
304.Bx
305versions of
306.Fn getopt
307set
308.Fa optopt
309to the last option character processed.
310However, this conflicts with
311.St -p1003.1
312which stipulates that
313.Fa optopt
314be set to the last character that caused an error.
315.Sh HISTORY
316The
317.Fn getopt
318function appeared in
319.Bx 4.3 .
320.Sh BUGS
321The
322.Fn getopt
323function was once specified to return
324.Dv EOF
325instead of \-1.
326This was changed by
327.St -p1003.2-92
328to decouple
329.Fn getopt
330from
331.Aq Pa stdio.h .
233.Pp 332.Pp
234It is also possible to handle digits as option letters. 333It is possible to handle digits as option letters.
235This allows 334This allows
236.Fn getopt 335.Fn getopt
237to be used with programs that expect a number 336to be used with programs that expect a number
238.Pq Dq Li \&-\&3 337.Pq Dq Li \-3
239as an option. 338as an option.
240This practice is wrong, and should not be used in any current development. 339This practice is wrong, and should not be used in any current development.
241It is provided for backward compatibility 340It is provided for backward compatibility
242.Em only . 341.Em only .
243The following code fragment works in most cases. 342The following code fragment works in most cases and can handle mixed
343number and letter arguments.
244.Bd -literal -offset indent 344.Bd -literal -offset indent
245int length; 345int aflag = 0, bflag = 0, ch, lastch = '\e0';
246char *p; 346int length = -1, newarg = 1, prevoptind = 1;
247 347
248while ((c = getopt(argc, argv, "0123456789")) != -1) 348while ((ch = getopt(argc, argv, "0123456789ab")) != -1) {
249 switch (c) { 349 switch (ch) {
250 case '0': case '1': case '2': case '3': case '4': 350 case '0': case '1': case '2': case '3': case '4':
251 case '5': case '6': case '7': case '8': case '9': 351 case '5': case '6': case '7': case '8': case '9':
252 p = argv[optind - 1]; 352 if (newarg || !isdigit(lastch))
253 if (p[0] == '-' && p[1] == ch && !p[2]) 353 length = 0;
254 length = atoi(++p); 354 else if (length > INT_MAX / 10)
255 else 355 usage();
256 length = atoi(argv[optind] + 1); 356 length = (length * 10) + (ch - '0');
257 break; 357 break;
358 case 'a':
359 aflag = 1;
360 break;
361 case 'b':
362 bflag = 1;
363 break;
364 default:
365 usage();
258 } 366 }
367 lastch = ch;
368 newarg = optind != prevoptind;
369 prevoptind = optind;
259} 370}
260.Ed 371.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"; */
36static char *rcsid = "$Id: getopt.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42
43int opterr = 1, /* if error message should be printed */
44 optind = 1, /* index into parent argv vector */
45 optopt, /* character checked for validity */
46 optreset; /* reset getopt */
47char *optarg; /* argument associated with option */
48
49#define BADCH (int)'?'
50#define BADARG (int)':'
51#define EMSG ""
52
53/*
54 * getopt --
55 * Parse argc/argv argument vector.
56 */
57int
58getopt(nargc, nargv, ostr)
59 int nargc;
60 char * const *nargv;
61 const char *ostr;
62{
63 extern char *__progname;
64 static char *place = EMSG; /* option letter processing */
65 char *oli; /* option letter list index */
66
67 if (optreset || !*place) { /* update scanning pointer */
68 optreset = 0;
69 if (optind >= nargc || *(place = nargv[optind]) != '-') {
70 place = EMSG;
71 return (-1);
72 }
73 if (place[1] && *++place == '-') { /* found "--" */
74 ++optind;
75 place = EMSG;
76 return (-1);
77 }
78 } /* option letter okay? */
79 if ((optopt = (int)*place++) == (int)':' ||
80 !(oli = strchr(ostr, optopt))) {
81 /*
82 * if the user didn't specify '-' as an option,
83 * assume it means -1.
84 */
85 if (optopt == (int)'-')
86 return (-1);
87 if (!*place)
88 ++optind;
89 if (opterr && *ostr != ':')
90 (void)fprintf(stderr,
91 "%s: illegal option -- %c\n", __progname, optopt);
92 return (BADCH);
93 }
94 if (*++oli != ':') { /* don't need argument */
95 optarg = NULL;
96 if (!*place)
97 ++optind;
98 }
99 else { /* need an argument */
100 if (*place) /* no white space */
101 optarg = place;
102 else if (nargc <= ++optind) { /* no arg */
103 place = EMSG;
104 if (*ostr == ':')
105 return (BADARG);
106 if (opterr)
107 (void)fprintf(stderr,
108 "%s: option requires an argument -- %c\n",
109 __progname, optopt);
110 return (BADCH);
111 }
112 else /* white space */
113 optarg = nargv[optind];
114 place = EMSG;
115 ++optind;
116 }
117 return (optopt); /* dump back option letter */
118}
diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3
new file mode 100644
index 0000000000..2bab963734
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.3
@@ -0,0 +1,464 @@
1.\" $OpenBSD: getopt_long.3,v 1.15 2007/07/03 12:06:07 jmc 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: July 3 2007 $
34.Dt GETOPT_LONG 3
35.Os
36.Sh NAME
37.Nm getopt_long ,
38.Nm getopt_long_only
39.Nd get long options from command line argument list
40.Sh SYNOPSIS
41.Fd #include <getopt.h>
42.Vt extern char *optarg;
43.Vt extern int optind;
44.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset;
47.Ft int
48.Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
49.Ft int
50.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
51.Sh DESCRIPTION
52The
53.Fn getopt_long
54function is similar to
55.Xr getopt 3
56but it accepts options in two forms: words and characters.
57The
58.Fn getopt_long
59function provides a superset of the functionality of
60.Xr getopt 3 .
61.Fn getopt_long
62can be used in two ways.
63In the first way, every long option understood by the program has a
64corresponding short option, and the option structure is only used to
65translate from long options to short options.
66When used in this fashion,
67.Fn getopt_long
68behaves identically to
69.Xr getopt 3 .
70This is a good way to add long option processing to an existing program
71with the minimum of rewriting.
72.Pp
73In the second mechanism, a long option sets a flag in the
74.Fa option
75structure passed, or will store a pointer to the command line argument
76in the
77.Fa option
78structure passed to it for options that take arguments.
79Additionally, the long option's argument may be specified as a single
80argument with an equal sign, e.g.
81.Bd -literal -offset indent
82$ myprogram --myoption=somevalue
83.Ed
84.Pp
85When a long option is processed, the call to
86.Fn getopt_long
87will return 0.
88For this reason, long option processing without
89shortcuts is not backwards compatible with
90.Xr getopt 3 .
91.Pp
92It is possible to combine these methods, providing for long options
93processing with short option equivalents for some options.
94Less frequently used options would be processed as long options only.
95.Pp
96Abbreviated long option names are accepted when
97.Fn getopt_long
98processes long options if the abbreviation is unique.
99An exact match is always preferred for a defined long option.
100.Pp
101The
102.Fn getopt_long
103call requires a structure to be initialized describing the long
104options.
105The structure is:
106.Bd -literal -offset indent
107struct option {
108 char *name;
109 int has_arg;
110 int *flag;
111 int val;
112};
113.Ed
114.Pp
115The
116.Fa name
117field should contain the option name without the leading double dash.
118.Pp
119The
120.Fa has_arg
121field should be one of:
122.Pp
123.Bl -tag -width "optional_argument" -compact -offset indent
124.It Dv no_argument
125no argument to the option is expected.
126.It Dv required_argument
127an argument to the option is required.
128.It Dv optional_argument
129an argument to the option may be presented.
130.El
131.Pp
132If
133.Fa flag
134is not
135.Dv NULL ,
136then the integer pointed to by it will be set to the value in the
137.Fa val
138field.
139If the
140.Fa flag
141field is
142.Dv NULL ,
143then the
144.Fa val
145field will be returned.
146Setting
147.Fa flag
148to
149.Dv NULL
150and setting
151.Fa val
152to the corresponding short option will make this function act just
153like
154.Xr getopt 3 .
155.Pp
156If the
157.Fa longindex
158field is not
159.Dv NULL ,
160then the integer pointed to by it will be set to the index of the long
161option relative to
162.Fa longopts .
163.Pp
164The last element of the
165.Fa longopts
166array has to be filled with zeroes.
167.Pp
168The
169.Fn getopt_long_only
170function behaves identically to
171.Fn getopt_long
172with the exception that long options may start with
173.Sq -
174in addition to
175.Sq -- .
176If an option starting with
177.Sq -
178does not match a long option but does match a single-character option,
179the single-character option is returned.
180.Sh RETURN VALUES
181If the
182.Fa flag
183field in
184.Li struct option
185is
186.Dv NULL ,
187.Fn getopt_long
188and
189.Fn getopt_long_only
190return the value specified in the
191.Fa val
192field, which is usually just the corresponding short option.
193If
194.Fa flag
195is not
196.Dv NULL ,
197these functions return 0 and store
198.Fa val
199in the location pointed to by
200.Fa flag .
201These functions return
202.Sq \:
203if there was a missing option argument,
204.Sq \&?
205if the user specified an unknown or ambiguous option, and
206\-1 when the argument list has been exhausted.
207.Sh EXAMPLES
208.Bd -literal
209int bflag, ch, fd;
210int daggerset;
211
212/* options descriptor */
213static struct option longopts[] = {
214 { "buffy", no_argument, NULL, 'b' },
215 { "fluoride", required_argument, NULL, 'f' },
216 { "daggerset", no_argument, &daggerset, 1 },
217 { NULL, 0, NULL, 0 }
218};
219
220bflag = 0;
221while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
222 switch (ch) {
223 case 'b':
224 bflag = 1;
225 break;
226 case 'f':
227 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
228 err(1, "unable to open %s", optarg);
229 break;
230 case 0:
231 if (daggerset)
232 fprintf(stderr, "Buffy will use her dagger to "
233 "apply fluoride to dracula's teeth\en");
234 break;
235 default:
236 usage();
237 /* NOTREACHED */
238 }
239argc -= optind;
240argv += optind;
241.Ed
242.Sh IMPLEMENTATION DIFFERENCES
243This section describes differences to the GNU implementation
244found in glibc-2.1.3:
245.Bl -bullet
246.It
247handling of
248.Ql -
249as the first character of the option string in the presence of the
250environment variable
251.Ev POSIXLY_CORRECT :
252.Bl -tag -width "OpenBSD"
253.It GNU
254ignores
255.Ev POSIXLY_CORRECT
256and returns non-options as arguments to option
257.Ql \e1 .
258.It OpenBSD
259honors
260.Ev POSIXLY_CORRECT
261and stops at the first non-option.
262.El
263.It
264handling of
265.Ql -
266within the option string (not the first character):
267.Bl -tag -width "OpenBSD"
268.It GNU
269treats a
270.Ql -
271on the command line as a non-argument.
272.It OpenBSD
273a
274.Ql -
275within the option string matches a
276.Ql -
277(single dash) on the command line.
278This functionality is provided for backward compatibility with
279programs, such as
280.Xr su 1 ,
281that use
282.Ql -
283as an option flag.
284This practice is wrong, and should not be used in any current development.
285.El
286.It
287handling of
288.Ql ::
289in the option string in the presence of
290.Ev POSIXLY_CORRECT :
291.Bl -tag -width "OpenBSD"
292.It Both
293GNU and
294.Ox
295ignore
296.Ev POSIXLY_CORRECT
297here and take
298.Ql ::
299to mean the preceding option takes an optional argument.
300.El
301.It
302return value in case of missing argument if first character
303(after
304.Ql +
305or
306.Ql - )
307in the option string is not
308.Ql \&: :
309.Bl -tag -width "OpenBSD"
310.It GNU
311returns
312.Ql \&?
313.It OpenBSD
314returns
315.Ql \&:
316(since
317.Ox Ns 's
318.Xr getopt 3
319does).
320.El
321.It
322handling of
323.Ql --a
324in
325.Xr getopt 3 :
326.Bl -tag -width "OpenBSD"
327.It GNU
328parses this as option
329.Ql - ,
330option
331.Ql a .
332.It OpenBSD
333parses this as
334.Ql -- ,
335and returns \-1 (ignoring the
336.Ql a )
337(because the original
338.Fn getopt
339did.)
340.El
341.It
342setting of
343.Va optopt
344for long options with
345.Va flag
346.No non- Ns Dv NULL :
347.Bl -tag -width "OpenBSD"
348.It GNU
349sets
350.Va optopt
351to
352.Va val .
353.It OpenBSD
354sets
355.Va optopt
356to 0 (since
357.Va val
358would never be returned).
359.El
360.It
361handling of
362.Ql -W
363with
364.Ql W;
365in the option string in
366.Xr getopt 3
367(not
368.Fn getopt_long ) :
369.Bl -tag -width "OpenBSD"
370.It GNU
371causes a segmentation fault.
372.It OpenBSD
373no special handling is done;
374.Ql W;
375is interpreted as two separate options, neither of which take an argument.
376.El
377.It
378setting of
379.Va optarg
380for long options without an argument that are invoked via
381.Ql -W
382(with
383.Ql W;
384in the option string):
385.Bl -tag -width "OpenBSD"
386.It GNU
387sets
388.Va optarg
389to the option name (the argument of
390.Ql -W ) .
391.It OpenBSD
392sets
393.Va optarg
394to
395.Dv NULL
396(the argument of the long option).
397.El
398.It
399handling of
400.Ql -W
401with an argument that is not (a prefix to) a known long option
402(with
403.Ql W;
404in the option string):
405.Bl -tag -width "OpenBSD"
406.It GNU
407returns
408.Ql -W
409with
410.Va optarg
411set to the unknown option.
412.It OpenBSD
413treats this as an error (unknown option) and returns
414.Ql \&?
415with
416.Va optopt
417set to 0 and
418.Va optarg
419set to
420.Dv NULL
421(as GNU's man page documents).
422.El
423.It
424The error messages are different.
425.It
426.Ox
427does not permute the argument vector at the same points in
428the calling sequence as GNU does.
429The aspects normally used by the caller
430(ordering after \-1 is returned, value of
431.Va optind
432relative to current positions) are the same, though.
433(We do fewer variable swaps.)
434.El
435.Sh ENVIRONMENT
436.Bl -tag -width Ev
437.It Ev POSIXLY_CORRECT
438If set, option processing stops when the first non-option is found and
439a leading
440.Sq -
441or
442.Sq +
443in the
444.Ar optstring
445is ignored.
446.El
447.Sh SEE ALSO
448.Xr getopt 3
449.Sh HISTORY
450The
451.Fn getopt_long
452and
453.Fn getopt_long_only
454functions first appeared in GNU libiberty.
455This implementation first appeared in
456.Ox 3.3 .
457.Sh BUGS
458The
459.Ar argv
460argument is not really
461.Dv const
462as its elements may be permuted (unless
463.Ev POSIXLY_CORRECT
464is 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..73d97c0ed3
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -0,0 +1,517 @@
1/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl 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#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
59
60#ifdef REPLACE_GETOPT
61int opterr = 1; /* if error message should be printed */
62int optind = 1; /* index into parent argv vector */
63int optopt = '?'; /* character checked for validity */
64int optreset; /* reset getopt */
65char *optarg; /* argument associated with option */
66#endif
67
68#define PRINT_ERROR ((opterr) && (*options != ':'))
69
70#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
71#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
72#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
73
74/* return values */
75#define BADCH (int)'?'
76#define BADARG ((*options == ':') ? (int)':' : (int)'?')
77#define INORDER (int)1
78
79#define EMSG ""
80
81static int getopt_internal(int, char * const *, const char *,
82 const struct option *, int *, int);
83static int parse_long_options(char * const *, const char *,
84 const struct option *, int *, int);
85static int gcd(int, int);
86static void permute_args(int, int, int, char * const *);
87
88static char *place = EMSG; /* option letter processing */
89
90/* XXX: set optreset to 1 rather than these two */
91static int nonopt_start = -1; /* first non option argument (for permute) */
92static int nonopt_end = -1; /* first option after non options (for permute) */
93
94/* Error messages */
95static const char recargchar[] = "option requires an argument -- %c";
96static const char recargstring[] = "option requires an argument -- %s";
97static const char ambig[] = "ambiguous option -- %.*s";
98static const char noarg[] = "option doesn't take an argument -- %.*s";
99static const char illoptchar[] = "unknown option -- %c";
100static const char illoptstring[] = "unknown option -- %s";
101
102/*
103 * Compute the greatest common divisor of a and b.
104 */
105static int
106gcd(int a, int b)
107{
108 int c;
109
110 c = a % b;
111 while (c != 0) {
112 a = b;
113 b = c;
114 c = a % b;
115 }
116
117 return (b);
118}
119
120/*
121 * Exchange the block from nonopt_start to nonopt_end with the block
122 * from nonopt_end to opt_end (keeping the same order of arguments
123 * in each block).
124 */
125static void
126permute_args(int panonopt_start, int panonopt_end, int opt_end,
127 char * const *nargv)
128{
129 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
130 char *swap;
131
132 /*
133 * compute lengths of blocks and number and size of cycles
134 */
135 nnonopts = panonopt_end - panonopt_start;
136 nopts = opt_end - panonopt_end;
137 ncycle = gcd(nnonopts, nopts);
138 cyclelen = (opt_end - panonopt_start) / ncycle;
139
140 for (i = 0; i < ncycle; i++) {
141 cstart = panonopt_end+i;
142 pos = cstart;
143 for (j = 0; j < cyclelen; j++) {
144 if (pos >= panonopt_end)
145 pos -= nnonopts;
146 else
147 pos += nopts;
148 swap = nargv[pos];
149 /* LINTED const cast */
150 ((char **) nargv)[pos] = nargv[cstart];
151 /* LINTED const cast */
152 ((char **)nargv)[cstart] = swap;
153 }
154 }
155}
156
157/*
158 * parse_long_options --
159 * Parse long options in argc/argv argument vector.
160 * Returns -1 if short_too is set and the option does not match long_options.
161 */
162static int
163parse_long_options(char * const *nargv, const char *options,
164 const struct option *long_options, int *idx, int short_too)
165{
166 char *current_argv, *has_equal;
167 size_t current_argv_len;
168 int i, match;
169
170 current_argv = place;
171 match = -1;
172
173 optind++;
174
175 if ((has_equal = strchr(current_argv, '=')) != NULL) {
176 /* argument found (--option=arg) */
177 current_argv_len = has_equal - current_argv;
178 has_equal++;
179 } else
180 current_argv_len = strlen(current_argv);
181
182 for (i = 0; long_options[i].name; i++) {
183 /* find matching long option */
184 if (strncmp(current_argv, long_options[i].name,
185 current_argv_len))
186 continue;
187
188 if (strlen(long_options[i].name) == current_argv_len) {
189 /* exact match */
190 match = i;
191 break;
192 }
193 /*
194 * If this is a known short option, don't allow
195 * a partial match of a single character.
196 */
197 if (short_too && current_argv_len == 1)
198 continue;
199
200 if (match == -1) /* partial match */
201 match = i;
202 else {
203 /* ambiguous abbreviation */
204 if (PRINT_ERROR)
205 warnx(ambig, (int)current_argv_len,
206 current_argv);
207 optopt = 0;
208 return (BADCH);
209 }
210 }
211 if (match != -1) { /* option found */
212 if (long_options[match].has_arg == no_argument
213 && has_equal) {
214 if (PRINT_ERROR)
215 warnx(noarg, (int)current_argv_len,
216 current_argv);
217 /*
218 * XXX: GNU sets optopt to val regardless of flag
219 */
220 if (long_options[match].flag == NULL)
221 optopt = long_options[match].val;
222 else
223 optopt = 0;
224 return (BADARG);
225 }
226 if (long_options[match].has_arg == required_argument ||
227 long_options[match].has_arg == optional_argument) {
228 if (has_equal)
229 optarg = has_equal;
230 else if (long_options[match].has_arg ==
231 required_argument) {
232 /*
233 * optional argument doesn't use next nargv
234 */
235 optarg = nargv[optind++];
236 }
237 }
238 if ((long_options[match].has_arg == required_argument)
239 && (optarg == NULL)) {
240 /*
241 * Missing argument; leading ':' indicates no error
242 * should be generated.
243 */
244 if (PRINT_ERROR)
245 warnx(recargstring,
246 current_argv);
247 /*
248 * XXX: GNU sets optopt to val regardless of flag
249 */
250 if (long_options[match].flag == NULL)
251 optopt = long_options[match].val;
252 else
253 optopt = 0;
254 --optind;
255 return (BADARG);
256 }
257 } else { /* unknown option */
258 if (short_too) {
259 --optind;
260 return (-1);
261 }
262 if (PRINT_ERROR)
263 warnx(illoptstring, current_argv);
264 optopt = 0;
265 return (BADCH);
266 }
267 if (idx)
268 *idx = match;
269 if (long_options[match].flag) {
270 *long_options[match].flag = long_options[match].val;
271 return (0);
272 } else
273 return (long_options[match].val);
274}
275
276/*
277 * getopt_internal --
278 * Parse argc/argv argument vector. Called by user level routines.
279 */
280static int
281getopt_internal(int nargc, char * const *nargv, const char *options,
282 const struct option *long_options, int *idx, int flags)
283{
284 char *oli; /* option letter list index */
285 int optchar, short_too;
286 static int posixly_correct = -1;
287
288 if (options == NULL)
289 return (-1);
290
291 /*
292 * Disable GNU extensions if POSIXLY_CORRECT is set or options
293 * string begins with a '+'.
294 */
295 if (posixly_correct == -1)
296 posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
297 if (posixly_correct || *options == '+')
298 flags &= ~FLAG_PERMUTE;
299 else if (*options == '-')
300 flags |= FLAG_ALLARGS;
301 if (*options == '+' || *options == '-')
302 options++;
303
304 /*
305 * XXX Some GNU programs (like cvs) set optind to 0 instead of
306 * XXX using optreset. Work around this braindamage.
307 */
308 if (optind == 0)
309 optind = optreset = 1;
310
311 optarg = NULL;
312 if (optreset)
313 nonopt_start = nonopt_end = -1;
314start:
315 if (optreset || !*place) { /* update scanning pointer */
316 optreset = 0;
317 if (optind >= nargc) { /* end of argument vector */
318 place = EMSG;
319 if (nonopt_end != -1) {
320 /* do permutation, if we have to */
321 permute_args(nonopt_start, nonopt_end,
322 optind, nargv);
323 optind -= nonopt_end - nonopt_start;
324 }
325 else if (nonopt_start != -1) {
326 /*
327 * If we skipped non-options, set optind
328 * to the first of them.
329 */
330 optind = nonopt_start;
331 }
332 nonopt_start = nonopt_end = -1;
333 return (-1);
334 }
335 if (*(place = nargv[optind]) != '-' ||
336 (place[1] == '\0' && strchr(options, '-') == NULL)) {
337 place = EMSG; /* found non-option */
338 if (flags & FLAG_ALLARGS) {
339 /*
340 * GNU extension:
341 * return non-option as argument to option 1
342 */
343 optarg = nargv[optind++];
344 return (INORDER);
345 }
346 if (!(flags & FLAG_PERMUTE)) {
347 /*
348 * If no permutation wanted, stop parsing
349 * at first non-option.
350 */
351 return (-1);
352 }
353 /* do permutation */
354 if (nonopt_start == -1)
355 nonopt_start = optind;
356 else if (nonopt_end != -1) {
357 permute_args(nonopt_start, nonopt_end,
358 optind, nargv);
359 nonopt_start = optind -
360 (nonopt_end - nonopt_start);
361 nonopt_end = -1;
362 }
363 optind++;
364 /* process next argument */
365 goto start;
366 }
367 if (nonopt_start != -1 && nonopt_end == -1)
368 nonopt_end = optind;
369
370 /*
371 * If we have "-" do nothing, if "--" we are done.
372 */
373 if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
374 optind++;
375 place = EMSG;
376 /*
377 * We found an option (--), so if we skipped
378 * non-options, we have to permute.
379 */
380 if (nonopt_end != -1) {
381 permute_args(nonopt_start, nonopt_end,
382 optind, nargv);
383 optind -= nonopt_end - nonopt_start;
384 }
385 nonopt_start = nonopt_end = -1;
386 return (-1);
387 }
388 }
389
390 /*
391 * Check long options if:
392 * 1) we were passed some
393 * 2) the arg is not just "-"
394 * 3) either the arg starts with -- we are getopt_long_only()
395 */
396 if (long_options != NULL && place != nargv[optind] &&
397 (*place == '-' || (flags & FLAG_LONGONLY))) {
398 short_too = 0;
399 if (*place == '-')
400 place++; /* --foo long option */
401 else if (*place != ':' && strchr(options, *place) != NULL)
402 short_too = 1; /* could be short option too */
403
404 optchar = parse_long_options(nargv, options, long_options,
405 idx, short_too);
406 if (optchar != -1) {
407 place = EMSG;
408 return (optchar);
409 }
410 }
411
412 if ((optchar = (int)*place++) == (int)':' ||
413 (optchar == (int)'-' && *place != '\0') ||
414 (oli = strchr(options, optchar)) == NULL) {
415 /*
416 * If the user specified "-" and '-' isn't listed in
417 * options, return -1 (non-option) as per POSIX.
418 * Otherwise, it is an unknown option character (or ':').
419 */
420 if (optchar == (int)'-' && *place == '\0')
421 return (-1);
422 if (!*place)
423 ++optind;
424 if (PRINT_ERROR)
425 warnx(illoptchar, optchar);
426 optopt = optchar;
427 return (BADCH);
428 }
429 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
430 /* -W long-option */
431 if (*place) /* no space */
432 /* NOTHING */;
433 else if (++optind >= nargc) { /* no arg */
434 place = EMSG;
435 if (PRINT_ERROR)
436 warnx(recargchar, optchar);
437 optopt = optchar;
438 return (BADARG);
439 } else /* white space */
440 place = nargv[optind];
441 optchar = parse_long_options(nargv, options, long_options,
442 idx, 0);
443 place = EMSG;
444 return (optchar);
445 }
446 if (*++oli != ':') { /* doesn't take argument */
447 if (!*place)
448 ++optind;
449 } else { /* takes (optional) argument */
450 optarg = NULL;
451 if (*place) /* no white space */
452 optarg = place;
453 else if (oli[1] != ':') { /* arg not optional */
454 if (++optind >= nargc) { /* no arg */
455 place = EMSG;
456 if (PRINT_ERROR)
457 warnx(recargchar, optchar);
458 optopt = optchar;
459 return (BADARG);
460 } else
461 optarg = nargv[optind];
462 }
463 place = EMSG;
464 ++optind;
465 }
466 /* dump back option letter */
467 return (optchar);
468}
469
470#ifdef REPLACE_GETOPT
471/*
472 * getopt --
473 * Parse argc/argv argument vector.
474 *
475 * [eventually this will replace the BSD getopt]
476 */
477int
478getopt(int nargc, char * const *nargv, const char *options)
479{
480
481 /*
482 * We don't pass FLAG_PERMUTE to getopt_internal() since
483 * the BSD getopt(3) (unlike GNU) has never done this.
484 *
485 * Furthermore, since many privileged programs call getopt()
486 * before dropping privileges it makes sense to keep things
487 * as simple (and bug-free) as possible.
488 */
489 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
490}
491#endif /* REPLACE_GETOPT */
492
493/*
494 * getopt_long --
495 * Parse argc/argv argument vector.
496 */
497int
498getopt_long(int nargc, char * const *nargv, const char *options,
499 const struct option *long_options, int *idx)
500{
501
502 return (getopt_internal(nargc, nargv, options, long_options, idx,
503 FLAG_PERMUTE));
504}
505
506/*
507 * getopt_long_only --
508 * Parse argc/argv argument vector.
509 */
510int
511getopt_long_only(int nargc, char * const *nargv, const char *options,
512 const struct option *long_options, int *idx)
513{
514
515 return (getopt_internal(nargc, nargv, options, long_options, idx,
516 FLAG_PERMUTE|FLAG_LONGONLY));
517}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..9f35df703f
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,145 @@
1.\" $OpenBSD: getsubopt.3,v 1.12 2007/05/31 19:19:31 jmc Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd $Mdocdate: May 31 2007 $
33.Dt GETSUBOPT 3
34.Os
35.Sh NAME
36.Nm getsubopt
37.Nd get sub options from an argument
38.Sh SYNOPSIS
39.Fd #include <stdlib.h>
40.Vt extern char *suboptarg;
41.Ft int
42.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
43.Sh DESCRIPTION
44The
45.Fn getsubopt
46function parses a string containing tokens delimited by one or more
47tab, space, or comma
48.Pq Ql \&,
49characters.
50It is intended for use in parsing groups of option arguments provided
51as part of a utility command line.
52.Pp
53The argument
54.Fa optionp
55is a pointer to a pointer to the string.
56The argument
57.Fa tokens
58is a pointer to a null-terminated array of pointers to strings.
59.Pp
60The
61.Fn getsubopt
62function returns the zero-based offset of the pointer in the
63.Fa tokens
64array referencing a string which matches the first token
65in the string, or \-1 if the string contains no tokens or
66.Fa tokens
67does not contain a matching string.
68.Pp
69If the token is of the form
70.Ar name Ns = Ns Ar value ,
71the location referenced by
72.Fa valuep
73will be set to point to the start of the
74.Dq value
75portion of the token.
76.Pp
77On return from
78.Fn getsubopt ,
79.Fa optionp
80will be set to point to the start of the next token in the string,
81or the NUL at the end of the string if no more tokens are present.
82The external variable
83.Fa suboptarg
84will be set to point to the start of the current token, or
85.Dv NULL
86if no tokens were present.
87The argument
88.Fa valuep
89will be set to point to the value portion of the token, or
90.Dv NULL
91if no value portion was present.
92.Sh EXAMPLES
93.Bd -literal
94char *tokens[] = {
95 #define ONE 0
96 "one",
97 #define TWO 1
98 "two",
99 NULL
100};
101
102\&...
103
104extern char *optarg, *suboptarg;
105char *options, *value;
106
107while ((ch = getopt(argc, argv, "ab:")) != -1) {
108 switch (ch) {
109 case 'a':
110 /* process ``a'' option */
111 break;
112 case 'b':
113 options = optarg;
114 while (*options) {
115 switch (getsubopt(&options, tokens, &value)) {
116 case ONE:
117 /* process ``one'' sub option */
118 break;
119 case TWO:
120 /* process ``two'' sub option */
121 if (!value)
122 error("no value for two");
123 i = atoi(value);
124 break;
125 case -1:
126 if (suboptarg)
127 error("illegal sub option %s",
128 suboptarg);
129 else
130 error("missing sub option");
131 break;
132 }
133 }
134 break;
135 }
136}
137.Ed
138.Sh SEE ALSO
139.Xr getopt 3 ,
140.Xr strsep 3
141.Sh HISTORY
142The
143.Fn getsubopt
144function 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 */
42char *suboptarg;
43
44int
45getsubopt(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..4ff17a087d
--- /dev/null
+++ b/src/lib/libc/stdlib/hcreate.3
@@ -0,0 +1,184 @@
1.\" $OpenBSD: hcreate.3,v 1.5 2008/06/26 05:42:05 ray Exp $
2.\" $NetBSD: hcreate.3,v 1.6 2003/04/16 13:34:46 wiz 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: June 26 2008 $
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
48The
49.Fn hcreate ,
50.Fn hdestroy ,
51and
52.Fn hsearch
53functions manage hash search tables.
54.Pp
55The
56.Fn hcreate
57function allocates and initializes the table.
58The
59.Fa nel
60argument specifies an estimate of the maximum number of entries to be held
61by the table.
62Unless further memory allocation fails, supplying an insufficient
63.Fa nel
64value will not result in functional harm, although a performance degradation
65may occur.
66Initialization using the
67.Fn hcreate
68function is mandatory prior to any access operations using
69.Fn hsearch .
70.Pp
71The
72.Fn hdestroy
73function destroys a table previously created using
74.Fn hcreate .
75After a call to
76.Fn hdestroy ,
77the data can no longer be accessed.
78.Pp
79The
80.Fn hsearch
81function is used to search to the hash table.
82It returns a pointer into the
83hash table indicating the address of an item.
84The
85.Fa item
86argument is of type
87.Dv ENTRY ,
88a structural type which contains the following members:
89.Pp
90.Bl -tag -compact -offset indent -width voidX*dataXX
91.It Fa char *key
92comparison key.
93.It Fa void *data
94pointer to data associated with
95.Fa key .
96.El
97.Pp
98The key comparison function used by
99.Fn hsearch
100is
101.Xr strcmp 3 .
102.Pp
103The
104.Fa action
105argument is of type
106.Dv ACTION ,
107an enumeration type which defines the following values:
108.Bl -tag -offset indent -width ENTERXX
109.It Dv ENTER
110Insert
111.Fa item
112into the hash table.
113If an existing item with the same key is found, it is not replaced.
114Note that the
115.Fa key
116and
117.Fa data
118elements of
119.Fa item
120are used directly by the new table entry.
121The storage for the
122key must not be modified during the lifetime of the hash table.
123.It Dv FIND
124Search the hash table without inserting
125.Fa item .
126.El
127.Sh RETURN VALUES
128If successful, the
129.Fn hcreate
130function returns a non-zero value.
131Otherwise, a value of 0 is returned and
132.Va errno
133is set to indicate the error.
134.Pp
135The
136.Fn hdestroy
137functions
138returns no value.
139.Pp
140If successful, the
141.Fn hsearch
142function returns a pointer to a hash table entry matching
143the provided key.
144If the action is
145.Dv FIND
146and the item was not found, or if the action is
147.Dv ENTER
148and the insertion failed,
149.Dv NULL
150is returned and
151.Va errno
152is set to indicate the error.
153If the action is
154.Dv ENTER
155and an entry already existed in the table matching the given
156key, the existing entry is returned and is not replaced.
157.Sh ERRORS
158The
159.Fn hcreate
160and
161.Fn hsearch
162functions will fail if:
163.Bl -tag -width Er
164.It Bq Er ENOMEM
165Insufficient memory is available.
166.El
167.Sh SEE ALSO
168.Xr bsearch 3 ,
169.Xr lsearch 3 ,
170.Xr malloc 3 ,
171.Xr strcmp 3
172.Sh STANDARDS
173These functions conform to
174.St -p1003.1-2004 .
175.Sh HISTORY
176The
177.Fn hcreate ,
178.Fn hdestroy
179and
180.Fn hsearch
181functions first appeared in
182.At V .
183.Sh BUGS
184The interface permits the use of only one hash table at a time.
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 */
67struct internal_entry {
68 SLIST_ENTRY(internal_entry) link;
69 ENTRY ent;
70};
71SLIST_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 */
84extern u_int32_t (*__default_hash)(const void *, size_t);
85
86static struct internal_head *htable;
87static size_t htablesize;
88
89int
90hcreate(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
133void
134hdestroy(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
155ENTRY *
156hsearch(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..e6fb61ba2f 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";*/
39static char *rcsid = "$Id: heapsort.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
141int 132int
142heapsort(vbase, nmemb, size, compar) 133heapsort(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 int 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/string/index.3 b/src/lib/libc/stdlib/imaxabs.3
index 847b03628b..10933e0a66 100644
--- a/src/lib/libc/string/index.3
+++ b/src/lib/libc/stdlib/imaxabs.3
@@ -2,7 +2,9 @@
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
5.\" Chris Torek. 5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
6.\" Redistribution and use in source and binary forms, with or without 8.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 9.\" modification, are permitted provided that the following conditions
8.\" are met: 10.\" are met:
@@ -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,53 +29,38 @@
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: @(#)index.3 5.3 (Berkeley) 4/19/91 32.\" $OpenBSD: imaxabs.3,v 1.3 2007/05/31 19:19:31 jmc Exp $
35.\" $Id: index.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 33.\"
37.Dd April 19, 1991 34.Dd $Mdocdate: May 31 2007 $
38.Dt INDEX 3 35.Dt IMAXABS 3
39.Os 36.Os
40.Sh NAME 37.Sh NAME
41.Nm index 38.Nm imaxabs
42.Nd locate character in string 39.Nd integer absolute value function
43.Sh SYNOPSIS 40.Sh SYNOPSIS
44.Fd #include <string.h> 41.Fd #include <inttypes.h>
45.Ft char * 42.Ft intmax_t
46.Fn index "const char *s" "int c" 43.Fn imaxabs "intmax_t j"
47.Sh DESCRIPTION 44.Sh DESCRIPTION
48The 45The
49.Fn index 46.Fn imaxabs
50function 47function computes the absolute value of the intmax_t variable
51locates the first character matching 48.Fa j .
52.Fa c
53(converted to a
54.Em char )
55in the null-terminated string
56.Fa s .
57.Sh RETURN VALUES 49.Sh RETURN VALUES
58The character 50The
59.Fa c 51.Fn imaxabs
60is returned if it is found; otherwise 52function returns the absolute value.
61.Dv NULL
62is returned.
63If
64.Fa c
65is '\e0',
66.Fn index
67locates the terminating '\e0'.
68.Sh SEE ALSO 53.Sh SEE ALSO
69.Xr memchr 3 , 54.Xr abs 3 ,
70.Xr rindex 3 , 55.Xr cabs 3 ,
71.Xr strchr 3 , 56.Xr floor 3 ,
72.Xr strcspn 3 , 57.Xr hypot 3 ,
73.Xr strpbrk 3 , 58.Xr labs 3 ,
74.Xr strrchr 3 , 59.Xr math 3
75.Xr strsep 3 , 60.Sh STANDARDS
76.Xr strspn 3 , 61The
77.Xr strstr 3 , 62.Fn abs
78.Xr strtok 3 63function conforms to
79.Sh HISTORY 64.St -ansiC-99 .
80A 65.Sh BUGS
81.Fn index 66The absolute value of the most negative integer remains negative.
82function appeared in
83.At v6 .
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
34intmax_t
35imaxabs(intmax_t j)
36{
37 return (j < 0 ? -j : j);
38}
diff --git a/src/lib/libc/string/rindex.3 b/src/lib/libc/stdlib/imaxdiv.3
index b13b3513e0..c4dee627aa 100644
--- a/src/lib/libc/string/rindex.3
+++ b/src/lib/libc/stdlib/imaxdiv.3
@@ -2,7 +2,9 @@
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
5.\" Chris Torek. 5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
6.\" Redistribution and use in source and binary forms, with or without 8.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 9.\" modification, are permitted provided that the following conditions
8.\" are met: 10.\" are met:
@@ -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,51 +29,39 @@
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: @(#)rindex.3 5.2 (Berkeley) 4/19/91 32.\" $OpenBSD: imaxdiv.3,v 1.3 2007/05/31 19:19:31 jmc Exp $
35.\" $Id: rindex.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 33.\"
37.Dd April 19, 1991 34.Dd $Mdocdate: May 31 2007 $
38.Dt RINDEX 3 35.Dt IMAXDIV 3
39.Os 36.Os
40.Sh NAME 37.Sh NAME
41.Nm rindex 38.Nm imaxdiv
42.Nd locate character in string 39.Nd return quotient and remainder from division
43.Sh SYNOPSIS 40.Sh SYNOPSIS
44.Fd #include <string.h> 41.Fd #include <inttypes.h>
45.Ft char * 42.Ft imaxdiv_t
46.Fn rindex "const char *s" "int c" 43.Fn imaxdiv "intmax_t num" "intmax_t denom"
47.Sh DESCRIPTION 44.Sh DESCRIPTION
48The 45The
49.Fn rindex 46.Fn imaxdiv
50function 47function computes the value
51locates the last character 48.Fa num Ns / Ns Fa denom
52matching 49and returns the quotient and remainder in a structure named
53.Fa c 50.Li imaxdiv_t
54(converted to a 51that contains two
55.Em char ) 52.Li intmax_t
56in the null-terminated string 53members named
57.Fa s . 54.Fa quot
58The character c is returned if it is found; otherwise NULL is returned. 55and
59If 56.Fa rem .
60.Fa c
61is
62.Ql \e0 ,
63.Fn rindex
64locates the terminating
65.Ql \e0 .
66.Sh SEE ALSO 57.Sh SEE ALSO
67.Xr index 3 , 58.Xr div 3 ,
68.Xr memchr 3 , 59.Xr ldiv 3 ,
69.Xr strchr 3 , 60.Xr lldiv 3 ,
70.Xr strcspn 3 , 61.Xr math 3 ,
71.Xr strpbrk 3 , 62.Xr qdiv 3
72.Xr strrchr 3 , 63.Sh STANDARDS
73.Xr strsep 3 , 64The
74.Xr strspn 3 , 65.Fn imaxdiv
75.Xr strstr 3 , 66function conforms to
76.Xr strtok 3 67.St -ansiC-99 .
77.Sh HISTORY
78A
79.Fn rindex
80function appeared in
81.At v6 .
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
36imaxdiv_t
37imaxdiv(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..dcb2b0d158
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: insque.3,v 1.7 2007/05/31 19:19:31 jmc Exp $
2.\" Copyright (c) 1993 John Brezak
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"
29.Dd $Mdocdate: May 31 2007 $
30.Dt INSQUE 3
31.Os
32.Sh NAME
33.Nm insque ,
34.Nm remque
35.Nd insert/remove element from a queue
36.Sh SYNOPSIS
37.Fd #include <search.h>
38.Ft void
39.Fn insque "void *elem" "void *pred"
40.Ft void
41.Fn remque "void *elem"
42.Sh DESCRIPTION
43.Bf -symbolic
44These interfaces have been superceded by the
45.Xr queue 3
46macros and are provided for compatibility with legacy code.
47.Ef
48.Pp
49.Fn insque
50and
51.Fn remque
52manipulate queues built from doubly linked lists.
53The queue can be either circular or linear.
54Each element in the queue must be of the following form:
55.Bd -literal -offset indent
56struct qelem {
57 struct qelem *q_forw;
58 struct qelem *q_back;
59 char q_data[];
60};
61.Ed
62.Pp
63The first two elements in the struct must be pointers of the
64same type that point to the previous and next elements in
65the queue respectively.
66Any subsequent data in the struct is application-dependent.
67.Pp
68The
69.Fn insque
70function inserts
71.Fa elem
72into a queue immediately after
73.Fa pred .
74.Pp
75The
76.Fn remque
77function removes
78.Fa elem
79from the queue.
80.Pp
81These functions are not atomic unless that machine architecture allows it.
82.Sh SEE ALSO
83.Xr queue 3
84.Sh STANDARDS
85The
86.Fn insque
87and
88.Fn remque
89functions conform to the
90.St -p1003.1-2001
91and
92.St -xpg4.3
93specifications.
94.Sh HISTORY
95The
96.Fn insque
97and
98.Fn remque
99functions are derived from the
100.Li insque
101and
102.Li remque
103instructions on the
104.Tn VAX .
105They 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
33struct qelem {
34 struct qelem *q_forw;
35 struct qelem *q_back;
36};
37
38void
39insque(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>
7static 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
12char * 10char *
13l64a (value) 11l64a(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..21c134fe5d 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.9 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt LABS 3 35.Dt LABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm labs 38.Nm labs, llabs
44.Nd return the absolute value of a long integer 39.Nd return the absolute value of a long integer
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
47.Ft long 42.Ft long
48.Fn labs "long j" 43.Fn labs "long i"
44.Ft long long
45.Fn llabs "long long j"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn labs 48.Fn labs
52function 49function returns the absolute value of the long integer
53returns the absolute value of the long integer 50.Fa i .
54.Ar j . 51The
52.Fn llabs
53function returns the absolute value of the long long integer
54.Fa j .
55.Sh SEE ALSO 55.Sh SEE ALSO
56.Xr abs 3 , 56.Xr abs 3 ,
57.Xr floor 3 ,
58.Xr cabs 3 , 57.Xr cabs 3 ,
58.Xr floor 3 ,
59.Xr imaxabs 3 ,
59.Xr math 3 60.Xr math 3
60.Sh STANDARDS 61.Sh STANDARDS
61The 62The
62.Fn labs 63.Fn labs
63function 64and
64conforms to 65.Fn llabs
65.St -ansiC . 66functions conform to
67.St -ansiC-99 .
66.Sh BUGS 68.Sh BUGS
67The absolute value of the most negative integer remains negative. 69The 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";*/
36static char *rcsid = "$Id: labs.c,v 1.1.1.1 1995/10/18 08:42:17 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41long 33long
42labs(j) 34labs(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..9627776899 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,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: @(#)ldiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: ldiv.3,v 1.9 2007/05/31 19:19:31 jmc Exp $
37.\" $Id: ldiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt LDIV 3 35.Dt LDIV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,24 +44,24 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn ldiv 46.Fn ldiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar ldiv_t 50.Li ldiv_t
57that contains two 51that contains two
58.Em long integer 52.Li long integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
65.Xr qdiv 3 , 59.Xr imaxdiv 3 ,
66.Xr math 3 60.Xr lldiv 3 ,
61.Xr math 3 ,
62.Xr qdiv 3
67.Sh STANDARDS 63.Sh STANDARDS
68The 64The
69.Fn ldiv 65.Fn ldiv
70function 66function conforms to
71conforms to
72.St -ansiC . 67.St -ansiC .
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";*/
39static char *rcsid = "$Id: ldiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <stdlib.h> /* ldiv_t */ 34#include <stdlib.h> /* ldiv_t */
43 35
44ldiv_t 36ldiv_t
45ldiv(num, denom) 37ldiv(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
34long long
35llabs(long long j)
36{
37 return (j < 0 ? -j : j);
38}
diff --git a/src/lib/libc/stdlib/memory.3 b/src/lib/libc/stdlib/lldiv.3
index 735252c837..a5be188ba2 100644
--- a/src/lib/libc/stdlib/memory.3
+++ b/src/lib/libc/stdlib/lldiv.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,39 @@
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: lldiv.3,v 1.2 2007/05/31 19:19:31 jmc 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: May 31 2007 $
36.Dt MEMORY 3 35.Dt LLDIV 3
37.Os BSD 4 36.Os
38.Sh NAME 37.Sh NAME
39.Nm malloc , 38.Nm lldiv
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.Fd #include <stdlib.h>
47.Ft void * 42.Ft lldiv_t
48.Fn malloc "size_t size" 43.Fn lldiv "long long num" "long long 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
58These functions allocate and free memory for the calling process. 45The
59They are described in the 46.Fn lldiv
60individual manual pages. 47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li lldiv_t
51that contains two
52.Li long long integer
53members named
54.Fa quot
55and
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 imaxdiv 3 ,
64.Xr malloc 3 , 60.Xr ldiv 3 ,
65.Xr realloc 3 , 61.Xr math 3 ,
66.Xr alloca 3 , 62.Xr qdiv 3
67.Sh STANDARDS 63.Sh STANDARDS
68These functions, with the exception of 64The
69.Fn alloca 65.Fn lldiv
70conform to 66function conforms to
71.St -ansiC . 67.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
36lldiv_t
37lldiv(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..e13ef4ec74
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.3
@@ -0,0 +1,108 @@
1.\" $OpenBSD: lsearch.3,v 1.8 2007/05/31 19:19:31 jmc 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: May 31 2007 $
33.Dt LSEARCH 3
34.Os
35.Sh NAME
36.Nm lsearch ,
37.Nm lfind
38.Nd linear searching routines
39.Sh SYNOPSIS
40.Fd #include <search.h>
41.Ft char *
42.Fn lsearch "const void *key" "const void *base" "size_t *nelp" \
43 "size_t width" "int (*compar)(void *, void *)"
44.Ft char *
45.Fn lfind "const void *key" "const void *base" "size_t *nelp" \
46 "size_t width" "int (*compar)(void *, void *)"
47.Sh DESCRIPTION
48The functions
49.Fn lsearch
50and
51.Fn lfind
52provide basic linear searching functionality.
53.Pp
54.Fa base
55is the pointer to the beginning of an array.
56The argument
57.Fa nelp
58is the current number of elements in the array, where each element
59is
60.Fa width
61bytes long.
62The
63.Fa compar
64function
65is a comparison routine which is used to compare two elements.
66It takes two arguments which point to the
67.Fa key
68object and to an array member, in that order, and must return an integer
69less than, equivalent to, or greater than zero if the
70.Fa key
71object is considered, respectively, to be less than, equal to, or greater
72than the array member.
73.Pp
74The
75.Fn lsearch
76and
77.Fn lfind
78functions
79return a pointer into the array referenced by
80.Fa base
81where
82.Fa key
83is located.
84If
85.Fa key
86does not exist,
87.Fn lfind
88will return a null pointer and
89.Fn lsearch
90will add it to the array.
91When an element is added to the array by
92.Fn lsearch ,
93the location referenced by the argument
94.Fa nelp
95is incremented by one.
96.Sh SEE ALSO
97.Xr bsearch 3 ,
98.Xr db 3
99.Sh STANDARDS
100The
101.Fn lsearch
102and
103.Fn lfind
104functions conform to the
105.St -p1003.1-2001
106and
107.St -xpg4.3
108specifications.
diff --git a/src/lib/libc/stdlib/lsearch.c b/src/lib/libc/stdlib/lsearch.c
new file mode 100644
index 0000000000..0815430199
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -0,0 +1,88 @@
1/* $OpenBSD: lsearch.c,v 1.3 2004/10/01 04:08:45 jsg 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#if defined(LIBC_SCCS) && !defined(lint)
36static char sccsid[] = "@(#)lsearch.c 8.1 (Berkeley) 6/4/93";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/types.h>
40#include <string.h>
41#include <search.h>
42
43typedef int (*cmp_fn_t)(const void *, const void *);
44static void *linear_base(const void *, const void *, size_t *, size_t,
45 cmp_fn_t, int);
46
47void *
48lsearch(const void *key, const void *base, size_t *nelp, size_t width,
49 cmp_fn_t compar)
50{
51
52 return(linear_base(key, base, nelp, width, compar, 1));
53}
54
55void *
56lfind(const void *key, const void *base, size_t *nelp, size_t width,
57 cmp_fn_t compar)
58{
59 return(linear_base(key, base, nelp, width, compar, 0));
60}
61
62static void *
63linear_base(const void *key, const void *base, size_t *nelp, size_t width,
64 cmp_fn_t compar, int add_flag)
65{
66 const char *element, *end;
67
68 end = (const char *)base + *nelp * width;
69 for (element = base; element < end; element += width)
70 if (!compar(key, element)) /* key found */
71 return((void *)element);
72
73 if (!add_flag) /* key not found */
74 return(NULL);
75
76 /*
77 * The UNIX System User's Manual, 1986 edition claims that
78 * a NULL pointer is returned by lsearch with errno set
79 * appropriately, if there is not enough room in the table
80 * to add a new item. This can't be done as none of these
81 * routines have any method of determining the size of the
82 * table. This comment isn't in the 1986-87 System V
83 * manual.
84 */
85 ++*nelp;
86 memcpy((void *)end, key, width);
87 return((void *)end);
88}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index 3bbf2bf65e..b9d62d04d0 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.54 2008/08/07 18:41:47 otto 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: August 7 2008 $
40.Dt MALLOC 3 36.Dt MALLOC 3
41.Os BSD 4 37.Os
42.Sh NAME 38.Sh NAME
43.Nm malloc 39.Nm malloc ,
44.Nd general memory allocation function 40.Nm calloc ,
41.Nm realloc ,
42.Nm free ,
43.Nm cfree
44.Nd memory allocation and deallocation
45.Sh SYNOPSIS 45.Sh SYNOPSIS
46.Fd #include <stdlib.h> 46.Fd #include <stdlib.h>
47.Ft void * 47.Ft void *
48.Fn malloc "size_t size" 48.Fn malloc "size_t size"
49.Ft void *
50.Fn calloc "size_t nmemb" "size_t size"
51.Ft void *
52.Fn realloc "void *ptr" "size_t size"
53.Ft void
54.Fn free "void *ptr"
55.Ft void
56.Fn cfree "void *ptr"
57.Ft char *
58.Va malloc_options ;
49.Sh DESCRIPTION 59.Sh DESCRIPTION
50The 60The
51.Fn malloc 61.Fn malloc
@@ -59,33 +69,388 @@ space from the appropriate list.
59.Pp 69.Pp
60The allocated space is 70The allocated space is
61suitably aligned (after possible pointer 71suitably aligned (after possible pointer
62coercion) for storage of any type of object. If the space is of 72coercion) for storage of any type of object.
73If the space is of
63.Em pagesize 74.Em pagesize
64or larger, the memory returned will be page-aligned. 75or larger, the memory returned will be page-aligned.
76.Pp
77Allocation of a zero size object returns a pointer to a zero size object.
78This zero size object is access protected, so any access to it will
79generate an exception (SIGSEGV).
80Many zero-sized objects can be placed consecutively in shared
81protected pages.
82The minimum size of the protection on each object is suitably aligned and
83sized as previously stated, but the protection may extend further depending
84on where in a protected zone the object lands.
85.Pp
86When using
87.Fn malloc
88be careful to avoid the following idiom:
89.Bd -literal -offset indent
90if ((p = malloc(num * size)) == NULL)
91 err(1, "malloc");
92.Ed
93.Pp
94The multiplication may lead to an integer overflow.
95To avoid this,
96.Fn calloc
97is recommended.
98.Pp
99If
100.Fn malloc
101must be used, be sure to test for overflow:
102.Bd -literal -offset indent
103if (size && num > SIZE_MAX / size) {
104 errno = ENOMEM;
105 err(1, "overflow");
106}
107.Ed
108.Pp
109The
110.Fn calloc
111function allocates space for an array of
112.Fa nmemb
113objects, each of whose size is
114.Fa size .
115The space is initialized to zero.
116The use of
117.Fn calloc
118is strongly encouraged when allocating multiple sized objects
119in order to avoid possible integer overflows.
120.Pp
121The
122.Fn free
123function causes the space pointed to by
124.Fa ptr
125to be either placed on a list of free pages to make it available for future
126allocation or, if required, to be returned to the kernel using
127.Xr munmap 2 .
128If
129.Fa ptr
130is a null pointer, no action occurs.
131.Pp
132A
133.Fn cfree
134function is also provided for compatibility with old systems and other
135.Nm malloc
136libraries; it is simply an alias for
137.Fn free .
138.Pp
139The
140.Fn realloc
141function changes the size of the object pointed to by
142.Fa ptr
143to
144.Fa size
145bytes and returns a pointer to the (possibly moved) object.
146The contents of the object are unchanged up to the lesser
147of the new and old sizes.
148If the new size is larger, the value of the newly allocated portion
149of the object is indeterminate and uninitialized.
150If
151.Fa ptr
152is a null pointer, the
153.Fn realloc
154function behaves like the
155.Fn malloc
156function for the specified size.
157If the space cannot be allocated, the object
158pointed to by
159.Fa ptr
160is unchanged.
161If
162.Fa size
163is zero and
164.Fa ptr
165is not a null pointer, the object it points to is freed and a new zero size
166object is returned.
167.Pp
168When using
169.Fn realloc
170be careful to avoid the following idiom:
171.Bd -literal -offset indent
172size += 50;
173if ((p = realloc(p, size)) == NULL)
174 return (NULL);
175.Ed
176.Pp
177Do not adjust the variable describing how much memory has been allocated
178until the allocation has been successful.
179This can cause aberrant program behavior if the incorrect size value is used.
180In most cases, the above sample will also result in a leak of memory.
181As stated earlier, a return value of
182.Dv NULL
183indicates that the old object still remains allocated.
184Better code looks like this:
185.Bd -literal -offset indent
186newsize = size + 50;
187if ((newp = realloc(p, newsize)) == NULL) {
188 free(p);
189 p = NULL;
190 size = 0;
191 return (NULL);
192}
193p = newp;
194size = newsize;
195.Ed
196.Pp
197As with
198.Fn malloc
199it is important to ensure the new size value will not overflow;
200i.e. avoid allocations like the following:
201.Bd -literal -offset indent
202if ((newp = realloc(p, num * size)) == NULL) {
203 ...
204.Ed
205.Pp
206Malloc will first look for a symbolic link called
207.Pa /etc/malloc.conf
208and next check the environment for a variable called
209.Ev MALLOC_OPTIONS
210and finally for the global variable
211.Va malloc_options
212and scan them for flags in that order.
213Flags are single letters, uppercase means on, lowercase means off.
214.Bl -tag -width indent
215.It Cm A
216.Dq Abort .
217.Fn malloc
218will coredump the process, rather than tolerate failure.
219This is a very handy debugging aid, since the core file will represent the
220time of failure, rather than when the null pointer was accessed.
221.It Cm D
222.Dq Dump .
223.Fn malloc
224will dump statistics in a file called
225.Pa malloc.out
226at exit.
227This option requires the library to have been compiled with -DMALLOC_STATS in
228order to have any effect.
229.It Cm F
230.Dq Freeguard .
231Enable use after free protection.
232Unused pages on the freelist are read and write protected to
233cause a segmentation fault upon access.
234.It Cm G
235.Dq Guard .
236Enable guard pages and chunk randomization.
237Each page size or larger allocation is followed by a guard page that will
238cause a segmentation fault upon any access.
239Smaller than page size chunks are returned in a random order.
240.It Cm H
241.Dq Hint .
242Pass a hint to the kernel about pages we don't use.
243If the machine is paging a lot this may help a bit.
244.It Cm J
245.Dq Junk .
246Fill some junk into the area allocated.
247Currently junk is bytes of 0xd0 when allocating; this is pronounced
248.Dq Duh .
249\&:-)
250Freed chunks are filled with 0xdf.
251.It Cm N
252Do not output warning messages when encountering possible corruption
253or bad pointers.
254.It Cm P
255.Dq Move allocations within a page.
256Allocations larger than half a page but smaller that a page
257are aligned to the end of a page to catch buffer overruns in more
258cases.
259.It Cm R
260.Dq realloc .
261Always reallocate when
262.Fn realloc
263is called, even if the initial allocation was big enough.
264This can substantially aid in compacting memory.
265.\".Pp
266.\".It Cm U
267.\".Dq utrace .
268.\"Generate entries for
269.\".Xr ktrace 1
270.\"for all operations.
271.\"Consult the source for this one.
272.It Cm X
273.Dq xmalloc .
274Rather than return failure,
275.Xr abort 3
276the program with a diagnostic message on stderr.
277It is the intention that this option be set at compile time by
278including in the source:
279.Bd -literal -offset indent
280extern char *malloc_options;
281malloc_options = "X";
282.Ed
283.Pp
284Note that this will cause code that is supposed to handle
285out-of-memory conditions gracefully to abort instead.
286.It Cm Z
287.Dq Zero .
288Fill some junk into the area allocated (see
289.Cm J ) ,
290except for the exact length the user asked for, which is zeroed.
291.It Cm <
292.Dq Half the cache size .
293Decrease the size of the free page cache by a factor of two.
294.It Cm >
295.Dq Double the cache size .
296Increase the size of the free page cache by a factor of two.
297.El
298.Pp
299So to set a systemwide reduction of cache size and coredumps on problems:
300.Li ln -s 'A<' /etc/malloc.conf
301.Pp
302The
303.Cm J
304and
305.Cm Z
306flags are mostly for testing and debugging.
307If a program changes behavior if either of these options are used,
308it is buggy.
309.Pp
310The default number of free pages cached is 64.
65.Sh RETURN VALUES 311.Sh RETURN VALUES
66The 312The
67.Fn malloc 313.Fn malloc
68function returns 314and
69a pointer to the allocated space if successful; otherwise 315.Fn calloc
70a null pointer is returned. 316functions return a pointer to the allocated space if successful; otherwise,
317a null pointer is returned and
318.Va errno
319is set to
320.Er ENOMEM .
321.Pp
322The
323.Fn free
324and
325.Fn cfree
326functions return no value.
327.Pp
328The
329.Fn realloc
330function returns a pointer to the (possibly moved) allocated space
331if successful; otherwise, a null pointer is returned and
332.Va errno
333is set to
334.Er ENOMEM .
335.Sh ENVIRONMENT
336.Bl -tag -width Ev
337.It Ev MALLOC_OPTIONS
338See above.
339.El
340.Sh FILES
341.Bl -tag -width "/etc/malloc.conf"
342.It Pa /etc/malloc.conf
343symbolic link to filename containing option flags
344.El
345.Sh DIAGNOSTICS
346If
347.Fn malloc ,
348.Fn calloc ,
349.Fn realloc ,
350or
351.Fn free
352detect an error or warning condition,
353a message will be printed to file descriptor
3542 (not using stdio).
355Errors will always result in the process being
356.Xr abort 3 'ed.
357If the
358.Cm A
359option has been specified, warnings will also
360.Xr abort 3
361the process.
362.Pp
363Here is a brief description of the error messages and what they mean:
364.Bl -tag -width Ds
365.It Dq out of memory
366If the
367.Cm A
368option is specified it is an error for
369.Fn malloc ,
370.Fn calloc ,
371or
372.Fn realloc
373to return
374.Dv NULL .
375.It Dq malloc init mmap failed
376This is a rather weird condition that is most likely to indicate a
377seriously overloaded system or a ulimit restriction.
378.It any other error
379.Fn malloc
380detected an internal error;
381consult sources and/or wizards.
382.El
383.Pp
384Here is a brief description of the warning messages and what they mean:
385.Bl -tag -width Ds
386.It Dq bogus pointer (double free?)
387An attempt to
388.Fn free
389or
390.Fn realloc
391an unallocated pointer was made.
392.It Dq chunk is already free
393There was an attempt to free a chunk that had already been freed.
394.It Dq modified chunk-pointer
395The pointer passed to
396.Fn free
397or
398.Fn realloc
399has been modified.
400.It Dq recursive call
401An attempt was made to call recursively into these functions, i.e., from a
402signal handler.
403This behavior is not supported.
404In particular, signal handlers should
405.Em not
406use any of the
407.Fn malloc
408functions nor utilize any other functions which may call
409.Fn malloc
410(e.g.,
411.Xr stdio 3
412routines).
413.It Dq unknown char in MALLOC_OPTIONS
414We found something we didn't understand.
415.It Dq malloc cache overflow/underflow
416The internal malloc page cache has been corrupted.
417.It Dq malloc free slot lost
418The internal malloc page cache has been corrupted.
419.It Dq guard size
420An inconsistent guard size was detected.
421.El
71.Sh SEE ALSO 422.Sh SEE ALSO
72.Xr brk 2 , 423.Xr brk 2 ,
73.Xr getpagesize 2 , 424.Xr mmap 2 ,
74.Xr free 3 , 425.Xr munmap 2 ,
75.Xr calloc 3 ,
76.Xr alloca 3 , 426.Xr alloca 3 ,
77.Xr realloc 3 , 427.Xr getpagesize 3
78.Xr memory 3
79.Sh STANDARDS 428.Sh STANDARDS
80The 429The
81.Fn malloc 430.Fn malloc
82function conforms to 431function conforms to
83.St -ansiC . 432.St -ansiC .
84.Sh BUGS 433.Sh HISTORY
85The current implementation of 434The present implementation of
86.Xr malloc 435.Fn malloc
87does not always fail gracefully when system 436started out as a filesystem on a drum
88memory limits are approached. 437attached to a 20-bit binary challenged computer built with discrete germanium
89It may fail to allocate memory when larger free blocks could be broken 438transistors, and it has since graduated to handle primary storage rather than
90up, or when limits are exceeded because the size is rounded up. 439secondary.
91It is optimized for sizes that are powers of two. 440.Pp
441The main difference from other
442.Fn malloc
443implementations are believed to be that
444the free pages are not accessed until allocated.
445Most
446.Fn malloc
447implementations will store a data structure containing a,
448possibly double-, linked list in the free chunks of memory, used to tie
449all the free memory together.
450That is a quite suboptimal thing to do.
451Every time the free-list is traversed, all the otherwise unused, and very
452likely paged out, pages get faulted into primary memory, just to see what
453lies after them in the list.
454.Pp
455On systems which are paging, this can increase the page-faults
456of a process by a factor of five.
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 3c57fad024..be80640e81 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,421 +1,1398 @@
1/* $OpenBSD: malloc.c,v 1.98 2008/08/25 17:56:17 otto Exp $ */
1/* 2/*
2 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Permission to use, copy, modify, and distribute this software for any
6 * modification, are permitted provided that the following conditions 6 * purpose with or without fee is hereby granted, provided that the above
7 * are met: 7 * 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 * 8 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11 * 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 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 15 * 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 */ 16 */
33 17
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/
36static char *rcsid = "$Id: malloc.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39/* 18/*
40 * malloc.c (Caltech) 2/21/82 19 * Parts of this code, mainly the sub page sized chunk management code is
41 * Chris Kingsley, kingsley@cit-20. 20 * derived from the malloc implementation with the following license:
42 * 21 */
43 * This is a very fast storage allocator. It allocates blocks of a small 22/*
44 * number of different sizes, and keeps free lists of each size. Blocks that 23 * ----------------------------------------------------------------------------
45 * don't exactly fit are passed up to the next larger size. In this 24 * "THE BEER-WARE LICENSE" (Revision 42):
46 * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long. 25 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
47 * This is designed for use in a virtual memory environment. 26 * can do whatever you want with this stuff. If we meet some day, and you think
27 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
28 * ----------------------------------------------------------------------------
48 */ 29 */
49 30
31/* #define MALLOC_STATS */
32
50#include <sys/types.h> 33#include <sys/types.h>
34#include <sys/param.h>
35#include <sys/mman.h>
36#include <sys/uio.h>
37#include <errno.h>
38#include <stdint.h>
51#include <stdlib.h> 39#include <stdlib.h>
52#include <string.h> 40#include <string.h>
41#include <stdio.h>
53#include <unistd.h> 42#include <unistd.h>
54 43
55#define NULL 0 44#ifdef MALLOC_STATS
56 45#include <fcntl.h>
57static void morecore();
58static int findbucket();
59
60/*
61 * The overhead on a block is at least 4 bytes. When free, this space
62 * contains a pointer to the next free block, and the bottom two bits must
63 * be zero. When in use, the first byte is set to MAGIC, and the second
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 */
70union overhead {
71 union overhead *ov_next; /* when free */
72 struct {
73 u_char ovu_magic; /* magic number */
74 u_char ovu_index; /* bucket # */
75#ifdef RCHECK
76 u_short ovu_rmagic; /* range magic number */
77 u_long ovu_size; /* actual block size */
78#endif 46#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};
85 47
86#define MAGIC 0xef /* magic # on accounting info */ 48#include "thread_private.h"
87#define RMAGIC 0x5555 /* magic # on range info */
88 49
89#ifdef RCHECK 50#define MALLOC_MINSHIFT 4
90#define RSLOP sizeof (u_short) 51#define MALLOC_MAXSHIFT 16
52
53#if defined(__sparc__) && !defined(__sparcv9__)
54#define MALLOC_PAGESHIFT (13U)
91#else 55#else
92#define RSLOP 0 56#define MALLOC_PAGESHIFT (PGSHIFT)
93#endif 57#endif
94 58
59#define MALLOC_PAGESIZE (1UL << MALLOC_PAGESHIFT)
60#define MALLOC_MINSIZE (1UL << MALLOC_MINSHIFT)
61#define MALLOC_PAGEMASK (MALLOC_PAGESIZE - 1)
62#define MASK_POINTER(p) ((void *)(((uintptr_t)(p)) & ~MALLOC_PAGEMASK))
63
64#define MALLOC_MAXCHUNK (1 << (MALLOC_PAGESHIFT-1))
65#define MALLOC_MAXCACHE 256
66#define MALLOC_DELAYED_CHUNKS 16 /* should be power of 2 */
67
68#define PAGEROUND(x) (((x) + (MALLOC_PAGEMASK)) & ~MALLOC_PAGEMASK)
69
95/* 70/*
96 * nextf[i] is the pointer to the next free block of size 2^(i+3). The 71 * What to use for Junk. This is the byte value we use to fill with
97 * smallest allocatable block is 8 bytes. The overhead information 72 * when the 'J' option is enabled. Use SOME_JUNK right after alloc,
98 * precedes the data area returned to the user. 73 * and SOME_FREEJUNK right before free.
99 */ 74 */
100#define NBUCKETS 30 75#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
101static union overhead *nextf[NBUCKETS]; 76#define SOME_FREEJUNK 0xdf
102extern char *sbrk(); 77
78#define MMAP(sz) mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
79 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
80
81struct region_info {
82 void *p; /* page; low bits used to mark chunks */
83 uintptr_t size; /* size for pages, or chunk_info pointer */
84};
85
86struct dir_info {
87 u_int32_t canary1;
88 struct region_info *r; /* region slots */
89 size_t regions_total; /* number of region slots */
90 size_t regions_bits; /* log2 of total */
91 size_t regions_free; /* number of free slots */
92 /* list of free chunk info structs */
93 struct chunk_info *chunk_info_list;
94 /* lists of chunks with free slots */
95 struct chunk_info *chunk_dir[MALLOC_MAXSHIFT];
96 size_t free_regions_size; /* free pages cached */
97 /* free pages cache */
98 struct region_info free_regions[MALLOC_MAXCACHE];
99 /* delayed free chunk slots */
100 void *delayed_chunks[MALLOC_DELAYED_CHUNKS];
101#ifdef MALLOC_STATS
102 size_t inserts;
103 size_t insert_collisions;
104 size_t finds;
105 size_t find_collisions;
106 size_t deletes;
107 size_t delete_moves;
108#define STATS_INC(x) ((x)++)
109#define STATS_ZERO(x) ((x) = 0)
110#else
111#define STATS_INC(x) /* nothing */
112#define STATS_ZERO(x) /* nothing */
113#endif /* MALLOC_STATS */
114 u_int32_t canary2;
115};
103 116
104static int pagesz; /* page size */
105static int pagebucket; /* page size bucket */
106 117
107#ifdef MSTATS
108/* 118/*
109 * nmalloc[i] is the difference between the number of mallocs and frees 119 * This structure describes a page worth of chunks.
110 * for a given block size. 120 *
121 * How many bits per u_long in the bitmap
111 */ 122 */
112static u_int nmalloc[NBUCKETS]; 123#define MALLOC_BITS (NBBY * sizeof(u_long))
113#include <stdio.h> 124struct chunk_info {
125 struct chunk_info *next; /* next on the free list */
126 void *page; /* pointer to the page */
127 u_int32_t canary;
128 u_short size; /* size of this page's chunks */
129 u_short shift; /* how far to shift for this size */
130 u_short free; /* how many free chunks */
131 u_short total; /* how many chunk */
132 /* which chunks are free */
133 u_long bits[(MALLOC_PAGESIZE / MALLOC_MINSIZE) / MALLOC_BITS];
134};
135
136static struct dir_info g_pool;
137static char *malloc_func; /* current function */
138char *malloc_options; /* compile-time options */
139
140static int malloc_abort = 1; /* abort() on error */
141static int malloc_active; /* status of malloc */
142static int malloc_freeprot; /* mprotect free pages PROT_NONE? */
143static int malloc_hint; /* call madvice on free pages? */
144static int malloc_junk; /* junk fill? */
145static int malloc_move; /* move allocations to end of page? */
146static int malloc_realloc; /* always realloc? */
147static int malloc_silent; /* avoid outputting warnings? */
148static int malloc_xmalloc; /* xmalloc behaviour? */
149static int malloc_zero; /* zero fill? */
150static size_t malloc_guard; /* use guard pages after allocations? */
151
152static u_int malloc_cache = 64; /* free pages we cache */
153static size_t malloc_guarded; /* bytes used for guards */
154static size_t malloc_used; /* bytes allocated */
155
156#ifdef MALLOC_STATS
157static int malloc_stats; /* dump statistics at end */
114#endif 158#endif
115 159
116#if defined(DEBUG) || defined(RCHECK) 160static size_t rbytesused; /* random bytes used */
117#define ASSERT(p) if (!(p)) botch("p") 161static u_char rbytes[4096]; /* random bytes */
118#include <stdio.h> 162static u_char getrbyte(void);
119static 163
120botch(s) 164extern char *__progname;
121 char *s; 165
166/* low bits of r->p determine size: 0 means >= page size and p->size holding
167 * real size, otherwise r->size is a shift count, or 1 for malloc(0)
168 */
169#define REALSIZE(sz, r) \
170 (sz) = (uintptr_t)(r)->p & MALLOC_PAGEMASK, \
171 (sz) = ((sz) == 0 ? (r)->size : ((sz) == 1 ? 0 : (1 << ((sz)-1))))
172
173static inline size_t
174hash(void *p)
122{ 175{
123 fprintf(stderr, "\r\nassertion botched: %s\r\n", s); 176 size_t sum;
124 (void) fflush(stderr); /* just in case user buffered it */ 177 union {
125 abort(); 178 uintptr_t p;
126} 179 unsigned short a[sizeof(void *) / sizeof(short)];
127#else 180 } u;
128#define ASSERT(p) 181 u.p = (uintptr_t)p >> MALLOC_PAGESHIFT;
182 sum = u.a[0];
183 sum = (sum << 7) - sum + u.a[1];
184#ifdef __LP64__
185 sum = (sum << 7) - sum + u.a[2];
186 sum = (sum << 7) - sum + u.a[3];
129#endif 187#endif
188 return sum;
189}
130 190
131void * 191#ifdef MALLOC_STATS
132malloc(nbytes) 192static void
133 size_t nbytes; 193dump_chunk(int fd, struct chunk_info *p, int fromfreelist)
134{ 194{
135 register union overhead *op; 195 char buf[64];
136 register long bucket, n;
137 register unsigned amt;
138 196
139 /* 197 while (p) {
140 * First time malloc is called, setup page size and 198 snprintf(buf, sizeof(buf), "chunk %d %d/%d %p\n", p->size,
141 * align break pointer so all data will be page aligned. 199 p->free, p->total, p->page);
142 */ 200 write(fd, buf, strlen(buf));
143 if (pagesz == 0) { 201 if (!fromfreelist)
144 pagesz = n = getpagesize(); 202 break;
145 op = (union overhead *)sbrk(0); 203 p = p->next;
146 n = n - sizeof (*op) - ((long)op & (n - 1)); 204 if (p != NULL) {
147 if (n < 0) 205 snprintf(buf, sizeof(buf), " ");
148 n += pagesz; 206 write(fd, buf, strlen(buf));
149 if (n) {
150 if (sbrk(n) == (char *)-1)
151 return (NULL);
152 } 207 }
153 bucket = 0; 208 }
154 amt = 8; 209}
155 while (pagesz > amt) { 210
156 amt <<= 1; 211static void
157 bucket++; 212dump_free_chunk_info(int fd, struct dir_info *d)
213{
214 char buf[64];
215 int i;
216
217 snprintf(buf, sizeof(buf), "Free chunk structs:\n");
218 write(fd, buf, strlen(buf));
219 for (i = 0; i < MALLOC_MAXSHIFT; i++) {
220 struct chunk_info *p = d->chunk_dir[i];
221 if (p != NULL) {
222 snprintf(buf, sizeof(buf), "%2d) ", i);
223 write(fd, buf, strlen(buf));
224 dump_chunk(fd, p, 1);
158 } 225 }
159 pagebucket = bucket;
160 } 226 }
161 /* 227
162 * Convert amount of memory requested into closest block size 228}
163 * stored in hash buckets which satisfies request. 229
164 * Account for space used per block for accounting. 230static void
165 */ 231dump_free_page_info(int fd, struct dir_info *d)
166 if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) { 232{
167#ifndef RCHECK 233 char buf[64];
168 amt = 8; /* size of first bucket */ 234 int i;
169 bucket = 0; 235
170#else 236 snprintf(buf, sizeof(buf), "Free pages cached: %zu\n",
171 amt = 16; /* size of first bucket */ 237 d->free_regions_size);
172 bucket = 1; 238 write(fd, buf, strlen(buf));
173#endif 239 for (i = 0; i < malloc_cache; i++) {
174 n = -((long)sizeof (*op) + RSLOP); 240 if (d->free_regions[i].p != NULL) {
175 } else { 241 snprintf(buf, sizeof(buf), "%2d) ", i);
176 amt = pagesz; 242 write(fd, buf, strlen(buf));
177 bucket = pagebucket; 243 snprintf(buf, sizeof(buf), "free at %p: %zu\n",
244 d->free_regions[i].p, d->free_regions[i].size);
245 write(fd, buf, strlen(buf));
246 }
178 } 247 }
179 while (nbytes > amt + n) { 248}
180 amt <<= 1; 249
181 if (amt == 0) 250static void
182 return (NULL); 251malloc_dump1(int fd, struct dir_info *d)
183 bucket++; 252{
253 char buf[64];
254 size_t i, realsize;
255
256 snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d);
257 write(fd, buf, strlen(buf));
258 snprintf(buf, sizeof(buf), "Regions slots %zu\n", d->regions_total);
259 write(fd, buf, strlen(buf));
260 snprintf(buf, sizeof(buf), "Finds %zu/%zu %f\n", d->finds,
261 d->find_collisions,
262 1.0 + (double)d->find_collisions / d->finds);
263 write(fd, buf, strlen(buf));
264 snprintf(buf, sizeof(buf), "Inserts %zu/%zu %f\n", d->inserts,
265 d->insert_collisions,
266 1.0 + (double)d->insert_collisions / d->inserts);
267 write(fd, buf, strlen(buf));
268 snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes,
269 d->delete_moves);
270 write(fd, buf, strlen(buf));
271 snprintf(buf, sizeof(buf), "Regions slots free %zu\n", d->regions_free);
272 write(fd, buf, strlen(buf));
273 for (i = 0; i < d->regions_total; i++) {
274 if (d->r[i].p != NULL) {
275 size_t h = hash(d->r[i].p) &
276 (d->regions_total - 1);
277 snprintf(buf, sizeof(buf), "%4zx) #%zx %zd ",
278 i, h, h - i);
279 write(fd, buf, strlen(buf));
280 REALSIZE(realsize, &d->r[i]);
281 if (realsize > MALLOC_MAXCHUNK) {
282 snprintf(buf, sizeof(buf),
283 "%p: %zu\n", d->r[i].p, realsize);
284 write(fd, buf, strlen(buf));
285 } else
286 dump_chunk(fd,
287 (struct chunk_info *)d->r[i].size, 0);
288 }
184 } 289 }
185 /* 290 dump_free_chunk_info(fd, d);
186 * If nothing in hash bucket right now, 291 dump_free_page_info(fd, d);
187 * request more memory from the system. 292 snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used);
188 */ 293 write(fd, buf, strlen(buf));
189 if ((op = nextf[bucket]) == NULL) { 294 snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded);
190 morecore(bucket); 295 write(fd, buf, strlen(buf));
191 if ((op = nextf[bucket]) == NULL) 296}
192 return (NULL); 297
193 } 298
194 /* remove from linked list */ 299void
195 nextf[bucket] = op->ov_next; 300malloc_dump(int fd)
196 op->ov_magic = MAGIC; 301{
197 op->ov_index = bucket; 302 malloc_dump1(fd, &g_pool);
198#ifdef MSTATS 303}
199 nmalloc[bucket]++; 304
200#endif 305static void
201#ifdef RCHECK 306malloc_exit(void)
202 /* 307{
203 * Record allocated size of block and 308 char *q = "malloc() warning: Couldn't dump stats\n";
204 * bound space with magic numbers. 309 int save_errno = errno, fd;
205 */ 310
206 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 311 fd = open("malloc.out", O_RDWR|O_APPEND);
207 op->ov_rmagic = RMAGIC; 312 if (fd != -1) {
208 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 313 malloc_dump(fd);
209#endif 314 close(fd);
210 return ((char *)(op + 1)); 315 } else
316 write(STDERR_FILENO, q, strlen(q));
317 errno = save_errno;
318}
319#endif /* MALLOC_STATS */
320
321
322
323static void
324wrterror(char *p)
325{
326 char *q = " error: ";
327 struct iovec iov[5];
328
329 iov[0].iov_base = __progname;
330 iov[0].iov_len = strlen(__progname);
331 iov[1].iov_base = malloc_func;
332 iov[1].iov_len = strlen(malloc_func);
333 iov[2].iov_base = q;
334 iov[2].iov_len = strlen(q);
335 iov[3].iov_base = p;
336 iov[3].iov_len = strlen(p);
337 iov[4].iov_base = "\n";
338 iov[4].iov_len = 1;
339 writev(STDERR_FILENO, iov, 5);
340
341#ifdef MALLOC_STATS
342 if (malloc_stats)
343 malloc_dump(STDERR_FILENO);
344#endif /* MALLOC_STATS */
345 //malloc_active--;
346 if (malloc_abort)
347 abort();
348}
349
350static void
351wrtwarning(char *p)
352{
353 char *q = " warning: ";
354 struct iovec iov[5];
355
356 if (malloc_abort)
357 wrterror(p);
358 else if (malloc_silent)
359 return;
360
361 iov[0].iov_base = __progname;
362 iov[0].iov_len = strlen(__progname);
363 iov[1].iov_base = malloc_func;
364 iov[1].iov_len = strlen(malloc_func);
365 iov[2].iov_base = q;
366 iov[2].iov_len = strlen(q);
367 iov[3].iov_base = p;
368 iov[3].iov_len = strlen(p);
369 iov[4].iov_base = "\n";
370 iov[4].iov_len = 1;
371
372 writev(STDERR_FILENO, iov, 5);
211} 373}
212 374
213/* 375/*
214 * Allocate more memory to the indicated bucket. 376 * Cache maintenance. We keep at most malloc_cache pages cached.
377 * If the cache is becoming full, unmap pages in the cache for real,
378 * and then add the region to the cache
379 * Opposed to the regular region data structure, the sizes in the
380 * cache are in MALLOC_PAGESIZE units.
215 */ 381 */
216static void 382static void
217morecore(bucket) 383unmap(struct dir_info *d, void *p, size_t sz)
218 int bucket;
219{ 384{
220 register union overhead *op; 385 size_t psz = sz >> MALLOC_PAGESHIFT;
221 register long sz; /* size of desired block */ 386 size_t rsz, tounmap;
222 long amt; /* amount to allocate */ 387 struct region_info *r;
223 int nblks; /* how many blocks we get */ 388 u_int i, offset;
224 389
225 /* 390 if (sz != PAGEROUND(sz)) {
226 * sbrk_size <= 0 only for big, FLUFFY, requests (about 391 wrterror("munmap round");
227 * 2^30 bytes on a VAX, I think) or for a negative arg.
228 */
229 sz = 1 << (bucket + 3);
230#ifdef DEBUG
231 ASSERT(sz > 0);
232#else
233 if (sz <= 0)
234 return; 392 return;
235#endif
236 if (sz < pagesz) {
237 amt = pagesz;
238 nblks = amt / sz;
239 } else {
240 amt = sz + pagesz;
241 nblks = 1;
242 } 393 }
243 op = (union overhead *)sbrk(amt); 394
244 /* no more room! */ 395 if (psz > malloc_cache) {
245 if ((long)op == -1) 396 if (munmap(p, sz))
246 return; 397 wrterror("munmap");
398 malloc_used -= sz;
399 return;
400 }
401 tounmap = 0;
402 rsz = malloc_cache - d->free_regions_size;
403 if (psz > rsz)
404 tounmap = psz - rsz;
405 d->free_regions_size -= tounmap;
406 offset = getrbyte();
407 for (i = 0; tounmap > 0 && i < malloc_cache; i++) {
408 r = &d->free_regions[(i + offset) & (malloc_cache - 1)];
409 if (r->p != NULL) {
410 if (r->size <= tounmap) {
411 rsz = r->size << MALLOC_PAGESHIFT;
412 if (munmap(r->p, rsz))
413 wrterror("munmap");
414 tounmap -= r->size;
415 r->p = NULL;
416 r->size = 0;
417 malloc_used -= rsz;
418 } else {
419 rsz = tounmap << MALLOC_PAGESHIFT;
420 if (munmap((char *)r->p + ((r->size - tounmap)
421 << MALLOC_PAGESHIFT), rsz))
422 wrterror("munmap");
423 r->size -= tounmap ;
424 tounmap = 0;
425 malloc_used -= rsz;
426 }
427 }
428 }
429 if (tounmap > 0)
430 wrtwarning("malloc cache underflow");
431 for (i = 0; i < malloc_cache; i++) {
432 r = &d->free_regions[i];
433 if (r->p == NULL) {
434 if (malloc_hint)
435 madvise(p, sz, MADV_FREE);
436 if (malloc_freeprot)
437 mprotect(p, sz, PROT_NONE);
438 r->p = p;
439 r->size = psz;
440 d->free_regions_size += psz;
441 break;
442 }
443 }
444 if (i == malloc_cache)
445 wrtwarning("malloc free slot lost");
446 if (d->free_regions_size > malloc_cache)
447 wrtwarning("malloc cache overflow");
448}
449
450static void *
451map(struct dir_info *d, size_t sz, int zero_fill)
452{
453 size_t psz = sz >> MALLOC_PAGESHIFT;
454 struct region_info *r, *big = NULL;
455 u_int i, offset;
456 void *p;
457
458 if (sz != PAGEROUND(sz)) {
459 wrterror("map round");
460 return NULL;
461 }
462 if (psz > d->free_regions_size) {
463 p = MMAP(sz);
464 if (p != MAP_FAILED)
465 malloc_used += sz;
466 /* zero fill not needed */
467 return p;
468 }
469 offset = getrbyte();
470 for (i = 0; i < malloc_cache; i++) {
471 r = &d->free_regions[(i + offset) & (malloc_cache - 1)];
472 if (r->p != NULL) {
473 if (r->size == psz) {
474 p = r->p;
475 if (malloc_freeprot)
476 mprotect(p, sz, PROT_READ | PROT_WRITE);
477 if (malloc_hint)
478 madvise(p, sz, MADV_NORMAL);
479 r->p = NULL;
480 r->size = 0;
481 d->free_regions_size -= psz;
482 if (zero_fill)
483 memset(p, 0, sz);
484 return p;
485 } else if (r->size > psz)
486 big = r;
487 }
488 }
489 if (big != NULL) {
490 r = big;
491 p = (char *)r->p + ((r->size - psz) << MALLOC_PAGESHIFT);
492 if (malloc_freeprot)
493 mprotect(p, sz, PROT_READ | PROT_WRITE);
494 if (malloc_hint)
495 madvise(p, sz, MADV_NORMAL);
496 r->size -= psz;
497 d->free_regions_size -= psz;
498 if (zero_fill)
499 memset(p, 0, sz);
500 return p;
501 }
502 p = MMAP(sz);
503 if (p != MAP_FAILED)
504 malloc_used += sz;
505 if (d->free_regions_size > malloc_cache)
506 wrtwarning("malloc cache");
507 /* zero fill not needed */
508 return p;
509}
510
511static void
512rbytes_init(void)
513{
514 arc4random_buf(rbytes, sizeof(rbytes));
515 rbytesused = 0;
516}
517
518static u_char
519getrbyte(void)
520{
521 if (rbytesused >= sizeof(rbytes))
522 rbytes_init();
523 return rbytes[rbytesused++];
524}
525
526/*
527 * Initialize a dir_info, which should have been cleared by caller
528 */
529static int
530omalloc_init(struct dir_info *d)
531{
532 char *p, b[64];
533 int i, j, save_errno = errno;
534 size_t regioninfo_size;
535
536 rbytes_init();
537
538 for (i = 0; i < 3; i++) {
539 switch (i) {
540 case 0:
541 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
542 if (j <= 0)
543 continue;
544 b[j] = '\0';
545 p = b;
546 break;
547 case 1:
548 if (issetugid() == 0)
549 p = getenv("MALLOC_OPTIONS");
550 else
551 continue;
552 break;
553 case 2:
554 p = malloc_options;
555 break;
556 default:
557 p = NULL;
558 }
559
560 for (; p != NULL && *p != '\0'; p++) {
561 switch (*p) {
562 case '>':
563 malloc_cache <<= 1;
564 if (malloc_cache > MALLOC_MAXCACHE)
565 malloc_cache = MALLOC_MAXCACHE;
566 break;
567 case '<':
568 malloc_cache >>= 1;
569 break;
570 case 'a':
571 malloc_abort = 0;
572 break;
573 case 'A':
574 malloc_abort = 1;
575 break;
576#ifdef MALLOC_STATS
577 case 'd':
578 malloc_stats = 0;
579 break;
580 case 'D':
581 malloc_stats = 1;
582 break;
583#endif /* MALLOC_STATS */
584 case 'f':
585 malloc_freeprot = 0;
586 break;
587 case 'F':
588 malloc_freeprot = 1;
589 break;
590 case 'g':
591 malloc_guard = 0;
592 break;
593 case 'G':
594 malloc_guard = MALLOC_PAGESIZE;
595 break;
596 case 'h':
597 malloc_hint = 0;
598 break;
599 case 'H':
600 malloc_hint = 1;
601 break;
602 case 'j':
603 malloc_junk = 0;
604 break;
605 case 'J':
606 malloc_junk = 1;
607 break;
608 case 'n':
609 malloc_silent = 0;
610 break;
611 case 'N':
612 malloc_silent = 1;
613 break;
614 case 'p':
615 malloc_move = 0;
616 break;
617 case 'P':
618 malloc_move = 1;
619 break;
620 case 'r':
621 malloc_realloc = 0;
622 break;
623 case 'R':
624 malloc_realloc = 1;
625 break;
626 case 'x':
627 malloc_xmalloc = 0;
628 break;
629 case 'X':
630 malloc_xmalloc = 1;
631 break;
632 case 'z':
633 malloc_zero = 0;
634 break;
635 case 'Z':
636 malloc_zero = 1;
637 break;
638 default:
639 j = malloc_abort;
640 malloc_abort = 0;
641 wrtwarning("unknown char in MALLOC_OPTIONS");
642 malloc_abort = j;
643 break;
644 }
645 }
646 }
647
247 /* 648 /*
248 * Add new memory allocated to that on 649 * We want junk in the entire allocation, and zero only in the part
249 * free list for this hash bucket. 650 * the user asked for.
250 */ 651 */
251 nextf[bucket] = op; 652 if (malloc_zero)
252 while (--nblks > 0) { 653 malloc_junk = 1;
253 op->ov_next = (union overhead *)((caddr_t)op + sz); 654
254 op = (union overhead *)((caddr_t)op + sz); 655#ifdef MALLOC_STATS
255 } 656 if (malloc_stats && (atexit(malloc_exit) == -1))
657 wrtwarning("atexit(2) failed."
658 " Will not be able to dump malloc stats on exit");
659#endif /* MALLOC_STATS */
660
661 errno = save_errno;
662
663 d->regions_bits = 9;
664 d->regions_free = d->regions_total = 1 << d->regions_bits;
665 regioninfo_size = d->regions_total * sizeof(struct region_info);
666 d->r = MMAP(regioninfo_size);
667 if (d->r == MAP_FAILED) {
668 wrterror("malloc init mmap failed");
669 d->regions_total = 0;
670 return 1;
671 }
672 malloc_used += regioninfo_size;
673 memset(d->r, 0, regioninfo_size);
674 d->canary1 = arc4random();
675 d->canary2 = ~d->canary1;
676 return 0;
256} 677}
257 678
258void 679static int
259free(cp) 680omalloc_grow(struct dir_info *d)
260 void *cp; 681{
261{ 682 size_t newbits;
262 register long size; 683 size_t newtotal;
263 register union overhead *op; 684 size_t newsize;
264 685 size_t mask;
265 if (cp == NULL) 686 size_t i;
266 return; 687 struct region_info *p;
267 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 688
268#ifdef DEBUG 689 if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 )
269 ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ 690 return 1;
270#else 691
271 if (op->ov_magic != MAGIC) 692 newbits = d->regions_bits + 1;
272 return; /* sanity */ 693 newtotal = d->regions_total * 2;
273#endif 694 newsize = newtotal * sizeof(struct region_info);
274#ifdef RCHECK 695 mask = newtotal - 1;
275 ASSERT(op->ov_rmagic == RMAGIC); 696
276 ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC); 697 p = MMAP(newsize);
277#endif 698 if (p == MAP_FAILED)
278 size = op->ov_index; 699 return 1;
279 ASSERT(size < NBUCKETS); 700
280 op->ov_next = nextf[size]; /* also clobbers ov_magic */ 701 malloc_used += newsize;
281 nextf[size] = op; 702 memset(p, 0, newsize);
282#ifdef MSTATS 703 STATS_ZERO(d->inserts);
283 nmalloc[size]--; 704 STATS_ZERO(d->insert_collisions);
284#endif 705 for (i = 0; i < d->regions_total; i++) {
706 void *q = d->r[i].p;
707 if (q != NULL) {
708 size_t index = hash(q) & mask;
709 STATS_INC(d->inserts);
710 while (p[index].p != NULL) {
711 index = (index - 1) & mask;
712 STATS_INC(d->insert_collisions);
713 }
714 p[index] = d->r[i];
715 }
716 }
717 /* avoid pages containing meta info to end up in cache */
718 if (munmap(d->r, d->regions_total * sizeof(struct region_info)))
719 wrterror("munmap");
720 else
721 malloc_used -= d->regions_total * sizeof(struct region_info);
722 d->regions_free = d->regions_free + d->regions_total;
723 d->regions_total = newtotal;
724 d->regions_bits = newbits;
725 d->r = p;
726 return 0;
727}
728
729static struct chunk_info *
730alloc_chunk_info(struct dir_info *d)
731{
732 struct chunk_info *p;
733 int i;
734
735 if (d->chunk_info_list == NULL) {
736 p = MMAP(MALLOC_PAGESIZE);
737 if (p == MAP_FAILED)
738 return NULL;
739 malloc_used += MALLOC_PAGESIZE;
740 for (i = 0; i < MALLOC_PAGESIZE / sizeof(*p); i++) {
741 p[i].next = d->chunk_info_list;
742 d->chunk_info_list = &p[i];
743 }
744 }
745 p = d->chunk_info_list;
746 d->chunk_info_list = p->next;
747 memset(p, 0, sizeof *p);
748 p->canary = d->canary1;
749 return p;
750}
751
752
753static void
754put_chunk_info(struct dir_info *d, struct chunk_info *p)
755{
756 p->next = d->chunk_info_list;
757 d->chunk_info_list = p;
758}
759
760static int
761insert(struct dir_info *d, void *p, size_t sz)
762{
763 size_t index;
764 size_t mask;
765 void *q;
766
767 if (d->regions_free * 4 < d->regions_total) {
768 if (omalloc_grow(d))
769 return 1;
770 }
771 mask = d->regions_total - 1;
772 index = hash(p) & mask;
773 q = d->r[index].p;
774 STATS_INC(d->inserts);
775 while (q != NULL) {
776 index = (index - 1) & mask;
777 q = d->r[index].p;
778 STATS_INC(d->insert_collisions);
779 }
780 d->r[index].p = p;
781 d->r[index].size = sz;
782 d->regions_free--;
783 return 0;
285} 784}
286 785
786static struct region_info *
787find(struct dir_info *d, void *p)
788{
789 size_t index;
790 size_t mask = d->regions_total - 1;
791 void *q, *r;
792
793 if (d->canary1 != ~d->canary2)
794 wrterror("internal struct corrupt");
795 p = MASK_POINTER(p);
796 index = hash(p) & mask;
797 r = d->r[index].p;
798 q = MASK_POINTER(r);
799 STATS_INC(d->finds);
800 while (q != p && r != NULL) {
801 index = (index - 1) & mask;
802 r = d->r[index].p;
803 q = MASK_POINTER(r);
804 STATS_INC(d->find_collisions);
805 }
806 return q == p ? &d->r[index] : NULL;
807}
808
809static void
810delete(struct dir_info *d, struct region_info *ri)
811{
812 /* algorithm R, Knuth Vol III section 6.4 */
813 size_t mask = d->regions_total - 1;
814 size_t i, j, r;
815
816 if (d->regions_total & (d->regions_total - 1))
817 wrterror("regions_total not 2^x");
818 d->regions_free++;
819 STATS_INC(g_pool.deletes);
820
821 i = ri - d->r;
822 for (;;) {
823 d->r[i].p = NULL;
824 d->r[i].size = 0;
825 j = i;
826 for (;;) {
827 i = (i - 1) & mask;
828 if (d->r[i].p == NULL)
829 return;
830 r = hash(d->r[i].p) & mask;
831 if ((i <= r && r < j) || (r < j && j < i) ||
832 (j < i && i <= r))
833 continue;
834 d->r[j] = d->r[i];
835 STATS_INC(g_pool.delete_moves);
836 break;
837 }
838
839 }
840}
841
287/* 842/*
288 * When a program attempts "storage compaction" as mentioned in the 843 * Allocate a page of chunks
289 * old malloc man page, it realloc's an already freed block. Usually
290 * this is the last block it freed; occasionally it might be farther
291 * back. We have to search all the free lists for the block in order
292 * to determine its bucket: 1st we make one pass thru the lists
293 * checking only the first block in each; if that fails we search
294 * ``realloc_srchlen'' blocks in each list for a match (the variable
295 * is extern so the caller can modify it). If that fails we just copy
296 * however many bytes was given to realloc() and hope it's not huge.
297 */ 844 */
298int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ 845static struct chunk_info *
846omalloc_make_chunks(struct dir_info *d, int bits)
847{
848 struct chunk_info *bp;
849 void *pp;
850 long i, k;
299 851
300void * 852 /* Allocate a new bucket */
301realloc(cp, nbytes) 853 pp = map(d, MALLOC_PAGESIZE, 0);
302 void *cp; 854 if (pp == MAP_FAILED)
303 size_t nbytes; 855 return NULL;
304{ 856
305 register u_long onb; 857 bp = alloc_chunk_info(d);
306 register long i; 858 if (bp == NULL) {
307 union overhead *op; 859 unmap(d, pp, MALLOC_PAGESIZE);
308 char *res; 860 return NULL;
309 int was_alloced = 0; 861 }
310 862
311 if (cp == NULL) 863 /* memory protect the page allocated in the malloc(0) case */
312 return (malloc(nbytes)); 864 if (bits == 0) {
313 op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); 865 bp->size = 0;
314 if (op->ov_magic == MAGIC) { 866 bp->shift = 1;
315 was_alloced++; 867 i = MALLOC_MINSIZE - 1;
316 i = op->ov_index; 868 while (i >>= 1)
317 } else { 869 bp->shift++;
318 /* 870 bp->total = bp->free = MALLOC_PAGESIZE >> bp->shift;
319 * Already free, doing "compaction". 871 bp->page = pp;
320 * 872
321 * Search for the old block of memory on the 873 k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE);
322 * free list. First, check the most common 874 if (k < 0) {
323 * case (last element free'd), then (this failing) 875 unmap(d, pp, MALLOC_PAGESIZE);
324 * the last ``realloc_srchlen'' items free'd. 876 put_chunk_info(d, bp);
325 * If all lookups fail, then assume the size of 877 return NULL;
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 */
332 if ((i = findbucket(op, 1)) < 0 &&
333 (i = findbucket(op, realloc_srchlen)) < 0)
334 i = NBUCKETS;
335 }
336 onb = 1 << (i + 3);
337 if (onb < pagesz)
338 onb -= sizeof (*op) + RSLOP;
339 else
340 onb += pagesz - sizeof (*op) - RSLOP;
341 /* avoid the copy if same size block */
342 if (was_alloced) {
343 if (i) {
344 i = 1 << (i + 2);
345 if (i < pagesz)
346 i -= sizeof (*op) + RSLOP;
347 else
348 i += pagesz - sizeof (*op) - RSLOP;
349 } 878 }
350 if (nbytes <= onb && nbytes > i) { 879 } else {
351#ifdef RCHECK 880 bp->size = (1UL << bits);
352 op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1); 881 bp->shift = bits;
353 *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; 882 bp->total = bp->free = MALLOC_PAGESIZE >> bits;
354#endif 883 bp->page = pp;
355 return(cp); 884 }
356 } else 885
357 free(cp); 886 /* set all valid bits in the bitmap */
358 } 887 k = bp->total;
359 if ((res = malloc(nbytes)) == NULL) 888 i = 0;
360 return (NULL); 889
361 if (cp != res) /* common optimization if "compacting" */ 890 /* Do a bunch at a time */
362 bcopy(cp, res, (nbytes < onb) ? nbytes : onb); 891 for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS)
363 return (res); 892 bp->bits[i / MALLOC_BITS] = ~0UL;
893
894 for (; i < k; i++)
895 bp->bits[i / MALLOC_BITS] |= 1UL << (i % MALLOC_BITS);
896
897 bp->next = d->chunk_dir[bits];
898 d->chunk_dir[bits] = bp;
899
900 bits++;
901 if ((uintptr_t)pp & bits)
902 wrterror("pp & bits");
903
904 insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp);
905 return bp;
364} 906}
365 907
908
366/* 909/*
367 * Search ``srchlen'' elements of each free list for a block whose 910 * Allocate a chunk
368 * header starts at ``freep''. If srchlen is -1 search the whole list.
369 * Return bucket number, or -1 if not found.
370 */ 911 */
371static 912static void *
372findbucket(freep, srchlen) 913malloc_bytes(struct dir_info *d, size_t size)
373 union overhead *freep;
374 int srchlen;
375{ 914{
376 register union overhead *p; 915 int i, j;
377 register int i, j; 916 size_t k;
917 u_long u, *lp;
918 struct chunk_info *bp;
919
920 /* Don't bother with anything less than this */
921 /* unless we have a malloc(0) requests */
922 if (size != 0 && size < MALLOC_MINSIZE)
923 size = MALLOC_MINSIZE;
378 924
379 for (i = 0; i < NBUCKETS; i++) { 925 /* Find the right bucket */
926 if (size == 0)
380 j = 0; 927 j = 0;
381 for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { 928 else {
382 if (p == freep) 929 j = MALLOC_MINSHIFT;
383 return (i); 930 i = (size - 1) >> (MALLOC_MINSHIFT - 1);
931 while (i >>= 1)
384 j++; 932 j++;
933 }
934
935 /* If it's empty, make a page more of that size chunks */
936 bp = d->chunk_dir[j];
937 if (bp == NULL && (bp = omalloc_make_chunks(d, j)) == NULL)
938 return NULL;
939
940 if (bp->canary != d->canary1)
941 wrterror("chunk info corrupted");
942 /* Find first word of bitmap which isn't empty */
943 for (lp = bp->bits; !*lp; lp++)
944 /* EMPTY */;
945
946 /* Find that bit, and tweak it */
947 u = 1;
948 k = 0;
949 while (!(*lp & u)) {
950 u += u;
951 k++;
952 }
953
954 /* advance a random # of positions */
955 i = (getrbyte() & (MALLOC_DELAYED_CHUNKS - 1)) % bp->free;
956 while (i > 0) {
957 u += u;
958 k++;
959 if (k >= MALLOC_BITS) {
960 lp++;
961 u = 1;
962 k = 0;
385 } 963 }
964 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) {
965 wrterror("chunk overflow");
966 errno = EFAULT;
967 return (NULL);
968 }
969 if (*lp & u)
970 i--;
386 } 971 }
387 return (-1); 972
973 *lp ^= u;
974
975 /* If there are no more free, remove from free-list */
976 if (!--bp->free) {
977 d->chunk_dir[j] = bp->next;
978 bp->next = NULL;
979 }
980 /* Adjust to the real offset of that chunk */
981 k += (lp - bp->bits) * MALLOC_BITS;
982 k <<= bp->shift;
983
984 if (malloc_junk && bp->size > 0)
985 memset((char *)bp->page + k, SOME_JUNK, bp->size);
986 return ((char *)bp->page + k);
388} 987}
389 988
390#ifdef MSTATS 989
391/* 990/*
392 * mstats - print out statistics about malloc 991 * Free a chunk, and possibly the page it's on, if the page becomes empty.
393 *
394 * Prints two lines of numbers, one showing the length of the free list
395 * for each size category, the second showing the number of mallocs -
396 * frees for each size category.
397 */ 992 */
398mstats(s) 993static void
399 char *s; 994free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
400{ 995{
401 register int i, j; 996 struct chunk_info *info, **mp;
402 register union overhead *p; 997 long i;
403 int totfree = 0, 998
404 totused = 0; 999 info = (struct chunk_info *)r->size;
405 1000 if (info->canary != d->canary1)
406 fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s); 1001 wrterror("chunk info corrupted");
407 for (i = 0; i < NBUCKETS; i++) { 1002
408 for (j = 0, p = nextf[i]; p; p = p->ov_next, j++) 1003 /* Find the chunk number on the page */
409 ; 1004 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
410 fprintf(stderr, " %d", j); 1005
411 totfree += j * (1 << (i + 3)); 1006 if ((uintptr_t)ptr & ((1UL << (info->shift)) - 1)) {
412 } 1007 wrtwarning("modified chunk-pointer");
413 fprintf(stderr, "\nused:\t"); 1008 return;
414 for (i = 0; i < NBUCKETS; i++) { 1009 }
415 fprintf(stderr, " %d", nmalloc[i]); 1010 if (info->bits[i / MALLOC_BITS] & (1UL << (i % MALLOC_BITS))) {
416 totused += nmalloc[i] * (1 << (i + 3)); 1011 wrtwarning("chunk is already free");
417 } 1012 return;
418 fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n", 1013 }
419 totused, totfree); 1014
1015 info->bits[i / MALLOC_BITS] |= 1UL << (i % MALLOC_BITS);
1016 info->free++;
1017
1018 if (info->size != 0)
1019 mp = d->chunk_dir + info->shift;
1020 else
1021 mp = d->chunk_dir;
1022
1023 if (info->free == 1) {
1024 /* Page became non-full */
1025
1026 /* Insert in address order */
1027 while (*mp != NULL && (*mp)->next != NULL &&
1028 (*mp)->next->page < info->page)
1029 mp = &(*mp)->next;
1030 info->next = *mp;
1031 *mp = info;
1032 return;
1033 }
1034 if (info->free != info->total)
1035 return;
1036
1037 /* Find & remove this page in the queue */
1038 while (*mp != info) {
1039 mp = &((*mp)->next);
1040 if (!*mp) {
1041 wrterror("not on queue");
1042 errno = EFAULT;
1043 return;
1044 }
1045 }
1046 *mp = info->next;
1047
1048 if (info->size == 0 && !malloc_freeprot)
1049 mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE);
1050 unmap(d, info->page, MALLOC_PAGESIZE);
1051
1052 delete(d, r);
1053 put_chunk_info(d, info);
420} 1054}
1055
1056
1057
1058static void *
1059omalloc(size_t sz, int zero_fill)
1060{
1061 void *p;
1062 size_t psz;
1063
1064 if (sz > MALLOC_MAXCHUNK) {
1065 if (sz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
1066 errno = ENOMEM;
1067 return NULL;
1068 }
1069 sz += malloc_guard;
1070 psz = PAGEROUND(sz);
1071 p = map(&g_pool, psz, zero_fill);
1072 if (p == MAP_FAILED) {
1073 errno = ENOMEM;
1074 return NULL;
1075 }
1076 if (insert(&g_pool, p, sz)) {
1077 unmap(&g_pool, p, psz);
1078 errno = ENOMEM;
1079 return NULL;
1080 }
1081 if (malloc_guard) {
1082 if (mprotect((char *)p + psz - malloc_guard,
1083 malloc_guard, PROT_NONE))
1084 wrterror("mprotect");
1085 malloc_guarded += malloc_guard;
1086 }
1087
1088 if (malloc_move &&
1089 sz - malloc_guard < MALLOC_PAGESIZE - MALLOC_MINSIZE) {
1090 /* fill whole allocation */
1091 if (malloc_junk)
1092 memset(p, SOME_JUNK, psz - malloc_guard);
1093 /* shift towards the end */
1094 p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_MINSIZE -
1095 (sz - malloc_guard)) & ~(MALLOC_MINSIZE-1));
1096 /* fill zeros if needed and overwritten above */
1097 if (zero_fill && malloc_junk)
1098 memset(p, 0, sz - malloc_guard);
1099 } else {
1100 if (malloc_junk) {
1101 if (zero_fill)
1102 memset(p + sz - malloc_guard,
1103 SOME_JUNK, psz - sz);
1104 else
1105 memset(p,
1106 SOME_JUNK, psz - malloc_guard);
1107 }
1108 }
1109
1110 } else {
1111 /* takes care of SOME_JUNK */
1112 p = malloc_bytes(&g_pool, sz);
1113 if (zero_fill && p != NULL && sz > 0)
1114 memset(p, 0, sz);
1115 }
1116
1117 return p;
1118}
1119
1120/*
1121 * Common function for handling recursion. Only
1122 * print the error message once, to avoid making the problem
1123 * potentially worse.
1124 */
1125static void
1126malloc_recurse(void)
1127{
1128 static int noprint;
1129
1130 if (noprint == 0) {
1131 noprint = 1;
1132 wrtwarning("recursive call");
1133 }
1134 malloc_active--;
1135 _MALLOC_UNLOCK();
1136 errno = EDEADLK;
1137}
1138
1139void *
1140malloc(size_t size)
1141{
1142 void *r;
1143
1144 _MALLOC_LOCK();
1145 malloc_func = " in malloc():";
1146 if (!g_pool.regions_total) {
1147 if (omalloc_init(&g_pool)) {
1148 _MALLOC_UNLOCK();
1149 if (malloc_xmalloc)
1150 wrterror("out of memory");
1151 errno = ENOMEM;
1152 return NULL;
1153 }
1154 }
1155 if (malloc_active++) {
1156 malloc_recurse();
1157 return NULL;
1158 }
1159 r = omalloc(size, malloc_zero);
1160 malloc_active--;
1161 _MALLOC_UNLOCK();
1162 if (r == NULL && malloc_xmalloc) {
1163 wrterror("out of memory");
1164 errno = ENOMEM;
1165 }
1166 return r;
1167}
1168
1169static void
1170ofree(void *p)
1171{
1172 struct region_info *r;
1173 size_t sz;
1174
1175 r = find(&g_pool, p);
1176 if (r == NULL) {
1177 wrtwarning("bogus pointer (double free?)");
1178 return;
1179 }
1180 REALSIZE(sz, r);
1181 if (sz > MALLOC_MAXCHUNK) {
1182 if (sz - malloc_guard >= MALLOC_PAGESIZE - MALLOC_MINSIZE) {
1183 if (r->p != p)
1184 wrtwarning("bogus pointer");
1185 } else {
1186#if notyetbecause_of_realloc
1187 /* shifted towards the end */
1188 if (p != ((char *)r->p) + ((MALLOC_PAGESIZE -
1189 MALLOC_MINSIZE - sz - malloc_guard) &
1190 ~(MALLOC_MINSIZE-1))) {
1191 }
421#endif 1192#endif
1193 p = r->p;
1194 }
1195 if (malloc_guard) {
1196 if (sz < malloc_guard)
1197 wrtwarning("guard size");
1198 if (!malloc_freeprot) {
1199 if (mprotect((char *)p + PAGEROUND(sz) -
1200 malloc_guard, malloc_guard,
1201 PROT_READ | PROT_WRITE))
1202 wrterror("mprotect");
1203 }
1204 malloc_guarded -= malloc_guard;
1205 }
1206 if (malloc_junk)
1207 memset(p, SOME_FREEJUNK, PAGEROUND(sz) - malloc_guard);
1208 unmap(&g_pool, p, PAGEROUND(sz));
1209 delete(&g_pool, r);
1210 } else {
1211 void *tmp;
1212 int i;
1213
1214 if (malloc_junk && sz > 0)
1215 memset(p, SOME_FREEJUNK, sz);
1216 i = getrbyte() & (MALLOC_DELAYED_CHUNKS - 1);
1217 tmp = p;
1218 p = g_pool.delayed_chunks[i];
1219 g_pool.delayed_chunks[i] = tmp;
1220 if (p != NULL) {
1221 r = find(&g_pool, p);
1222 if (r == NULL) {
1223 wrtwarning("bogus pointer (double free?)");
1224 return;
1225 }
1226 free_bytes(&g_pool, r, p);
1227 }
1228 }
1229}
1230
1231void
1232free(void *ptr)
1233{
1234 /* This is legal. */
1235 if (ptr == NULL)
1236 return;
1237
1238 _MALLOC_LOCK();
1239 malloc_func = " in free():";
1240 if (malloc_active++) {
1241 malloc_recurse();
1242 return;
1243 }
1244 ofree(ptr);
1245 malloc_active--;
1246 _MALLOC_UNLOCK();
1247}
1248
1249
1250static void *
1251orealloc(void *p, size_t newsz)
1252{
1253 struct region_info *r;
1254 size_t oldsz, goldsz, gnewsz;
1255 void *q;
1256
1257 if (p == NULL)
1258 return omalloc(newsz, 0);
1259
1260 r = find(&g_pool, p);
1261 if (r == NULL) {
1262 wrtwarning("bogus pointer (double free?)");
1263 return NULL;
1264 }
1265 if (newsz >= SIZE_MAX - malloc_guard - MALLOC_PAGESIZE) {
1266 errno = ENOMEM;
1267 return NULL;
1268 }
1269
1270 REALSIZE(oldsz, r);
1271 goldsz = oldsz;
1272 if (oldsz > MALLOC_MAXCHUNK) {
1273 if (oldsz < malloc_guard)
1274 wrtwarning("guard size");
1275 oldsz -= malloc_guard;
1276 }
1277
1278 gnewsz = newsz;
1279 if (gnewsz > MALLOC_MAXCHUNK)
1280 gnewsz += malloc_guard;
1281
1282 if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p &&
1283 !malloc_realloc) {
1284 size_t roldsz = PAGEROUND(goldsz);
1285 size_t rnewsz = PAGEROUND(gnewsz);
1286
1287 if (rnewsz < roldsz) {
1288 if (malloc_guard) {
1289 if (mprotect((char *)p + roldsz - malloc_guard,
1290 malloc_guard, PROT_READ | PROT_WRITE))
1291 wrterror("mprotect");
1292 if (mprotect((char *)p + rnewsz - malloc_guard,
1293 malloc_guard, PROT_NONE))
1294 wrterror("mprotect");
1295 }
1296 unmap(&g_pool, (char *)p + rnewsz, roldsz - rnewsz);
1297 r->size = gnewsz;
1298 return p;
1299 } else if (rnewsz == roldsz) {
1300 if (newsz > oldsz && malloc_junk)
1301 memset((char *)p + newsz, SOME_JUNK,
1302 rnewsz - malloc_guard - newsz);
1303 r->size = gnewsz;
1304 return p;
1305 }
1306 }
1307 if (newsz <= oldsz && newsz > oldsz / 2 && !malloc_realloc) {
1308 if (malloc_junk && newsz > 0)
1309 memset((char *)p + newsz, SOME_JUNK, oldsz - newsz);
1310 return p;
1311 } else if (newsz != oldsz || malloc_realloc) {
1312 q = omalloc(newsz, 0);
1313 if (q == NULL)
1314 return NULL;
1315 if (newsz != 0 && oldsz != 0)
1316 memcpy(q, p, oldsz < newsz ? oldsz : newsz);
1317 ofree(p);
1318 return q;
1319 } else
1320 return p;
1321}
1322
1323void *
1324realloc(void *ptr, size_t size)
1325{
1326 void *r;
1327
1328 _MALLOC_LOCK();
1329 malloc_func = " in realloc():";
1330 if (!g_pool.regions_total) {
1331 if (omalloc_init(&g_pool)) {
1332 _MALLOC_UNLOCK();
1333 if (malloc_xmalloc)
1334 wrterror("out of memory");
1335 errno = ENOMEM;
1336 return NULL;
1337 }
1338 }
1339 if (malloc_active++) {
1340 malloc_recurse();
1341 return NULL;
1342 }
1343
1344 r = orealloc(ptr, size);
1345
1346 malloc_active--;
1347 _MALLOC_UNLOCK();
1348 if (r == NULL && malloc_xmalloc) {
1349 wrterror("out of memory");
1350 errno = ENOMEM;
1351 }
1352 return r;
1353}
1354
1355
1356#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
1357
1358void *
1359calloc(size_t nmemb, size_t size)
1360{
1361 void *r;
1362
1363 _MALLOC_LOCK();
1364 malloc_func = " in calloc():";
1365 if (!g_pool.regions_total) {
1366 if (omalloc_init(&g_pool)) {
1367 _MALLOC_UNLOCK();
1368 if (malloc_xmalloc)
1369 wrterror("out of memory");
1370 errno = ENOMEM;
1371 return NULL;
1372 }
1373 }
1374 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1375 nmemb > 0 && SIZE_MAX / nmemb < size) {
1376 _MALLOC_UNLOCK();
1377 if (malloc_xmalloc)
1378 wrterror("out of memory");
1379 errno = ENOMEM;
1380 return NULL;
1381 }
1382
1383 if (malloc_active++) {
1384 malloc_recurse();
1385 return NULL;
1386 }
1387
1388 size *= nmemb;
1389 r = omalloc(size, 1);
1390
1391 malloc_active--;
1392 _MALLOC_UNLOCK();
1393 if (r == NULL && malloc_xmalloc) {
1394 wrterror("out of memory");
1395 errno = ENOMEM;
1396 }
1397 return r;
1398}
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
index 381fdc0830..623f652134 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.8 2005/08/08 08:05:37 espie 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";*/
39static char *rcsid = "$Id: merge.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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
62static void setup __P((u_char *, u_char *, size_t, size_t, int (*)())); 54static void setup(u_char *, u_char *, size_t, size_t, int (*)());
63static void insertionsort __P((u_char *, size_t, size_t, int (*)())); 55static 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 */
98int 90int
99mergesort(base, nmemb, size, cmp) 91mergesort(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 */
151LINEAR: 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;
172SLOWCASE: 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,10 +245,8 @@ COPY: b = t;
256 * is defined. Otherwise simple pairwise merging is used.) 245 * is defined. Otherwise simple pairwise merging is used.)
257 */ 246 */
258void 247void
259setup(list1, list2, n, size, cmp) 248setup(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, tmp, sense;
265 u_char *f1, *f2, *s, *l2, *last, *p2; 252 u_char *f1, *f2, *s, *l2, *last, *p2;
@@ -330,10 +317,8 @@ setup(list1, list2, n, size, cmp)
330 * last 4 elements. 317 * last 4 elements.
331 */ 318 */
332static void 319static void
333insertionsort(a, n, size, cmp) 320insertionsort(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";*/
36static char *rcsid = "$Id: multibyte.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
47int
48mblen(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*/
60int
61mbtowc(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*/
76int
77#ifdef __STDC__
78wctomb(char *s, wchar_t wchar)
79#else
80wctomb(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*/
93size_t
94mbstowcs(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*/
113size_t
114wcstombs(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/putenv.c b/src/lib/libc/stdlib/putenv.c
index 2194c2c608..54482f6a14 100644
--- a/src/lib/libc/stdlib/putenv.c
+++ b/src/lib/libc/stdlib/putenv.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: putenv.c,v 1.5 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, 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,29 +28,23 @@
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";*/
36static char *rcsid = "$Id: putenv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
42int 34int
43putenv(str) 35putenv(const char *str)
44 const char *str;
45{ 36{
46 register char *p, *equal; 37 char *p, *equal;
47 int rval; 38 int rval;
48 39
49 if (!(p = strdup(str))) 40 if ((p = strdup(str)) == NULL)
50 return(1); 41 return (-1);
51 if (!(equal = strchr(p, '='))) { 42 if ((equal = strchr(p, '=')) == NULL) {
52 (void)free(p); 43 (void)free(p);
53 return(1); 44 return (-1);
54 } 45 }
55 *equal = '\0'; 46 *equal = '\0';
56 rval = setenv(p, equal + 1, 1); 47 rval = setenv(p, equal + 1, 1);
57 (void)free(p); 48 (void)free(p);
58 return(rval); 49 return (rval);
59} 50}
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
index cb1e052191..e022e9c1f4 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,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: @(#)labs.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qabs.3,v 1.11 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt QABS 3 35.Dt QABS 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,14 +44,14 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qabs 46.Fn qabs
52function 47function returns the absolute value of the quad integer
53returns the absolute value of the quad integer 48.Fa j .
54.Ar j .
55.Sh SEE ALSO 49.Sh SEE ALSO
56.Xr abs 3 , 50.Xr abs 3 ,
57.Xr labs 3 ,
58.Xr floor 3 ,
59.Xr cabs 3 , 51.Xr cabs 3 ,
52.Xr floor 3 ,
53.Xr imaxabs 3 ,
54.Xr labs 3 ,
60.Xr math 3 55.Xr math 3
61.Sh BUGS 56.Sh BUGS
62The absolute value of the most negative integer remains negative. 57The 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";*/
36static char *rcsid = "$Id: qabs.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40 32
41quad_t 33quad_t
42qabs(j) 34qabs(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..59776bdf2d 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,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: @(#)qdiv.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: qdiv.3,v 1.8 2007/05/31 19:19:31 jmc Exp $
37.\" $Id: qdiv.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt QDIV 3 35.Dt QDIV 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,18 +44,19 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn qdiv 46.Fn qdiv
52function 47function computes the value
53computes the value 48.Fa num Ns / Ns Fa denom
54.Ar num/denom
55and returns the quotient and remainder in a structure named 49and returns the quotient and remainder in a structure named
56.Ar qdiv_t 50.Li qdiv_t
57that contains two 51that contains two
58.Em quad integer 52.Li quad integer
59members named 53members named
60.Ar quot 54.Fa quot
61and 55and
62.Ar rem . 56.Fa rem .
63.Sh SEE ALSO 57.Sh SEE ALSO
64.Xr div 3 , 58.Xr div 3 ,
59.Xr imaxdiv 3 ,
65.Xr ldiv 3 , 60.Xr ldiv 3 ,
61.Xr lldiv 3 ,
66.Xr math 3 62.Xr math 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";*/
39static char *rcsid = "$Id: qdiv.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <stdlib.h> /* qdiv_t */ 34#include <stdlib.h> /* qdiv_t */
43 35
44qdiv_t 36qdiv_t
45qdiv(num, denom) 37qdiv(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..92c75d5365 100644
--- a/src/lib/libc/stdlib/qsort.3
+++ b/src/lib/libc/stdlib/qsort.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,15 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)qsort.3 8.1 (Berkeley) 6/4/93 32.\" $OpenBSD: qsort.3,v 1.15 2007/05/31 19:19:31 jmc Exp $
37.\" $Id: qsort.3,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $
38.\" 33.\"
39.Dd June 4, 1993 34.Dd $Mdocdate: May 31 2007 $
40.Dt QSORT 3 35.Dt QSORT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm qsort, heapsort, mergesort 38.Nm qsort ,
39.Nm heapsort ,
40.Nm mergesort
44.Nd sort functions 41.Nd sort functions
45.Sh SYNOPSIS 42.Sh SYNOPSIS
46.Fd #include <stdlib.h> 43.Fd #include <stdlib.h>
@@ -72,7 +69,7 @@ objects, the initial member of which is pointed to by
72.Fa base . 69.Fa base .
73The size of each object is specified by 70The size of each object is specified by
74.Fa size . 71.Fa size .
75.Fn Mergesort 72.Fn mergesort
76behaves similarly, but 73behaves similarly, but
77.Em requires 74.Em requires
78that 75that
@@ -106,51 +103,49 @@ is stable.
106.Pp 103.Pp
107The 104The
108.Fn qsort 105.Fn qsort
109function is an implementation of C.A.R. Hoare's ``quicksort'' algorithm, 106function is an implementation of C.A.R. Hoare's
107.Dq quicksort
108algorithm,
110a variant of partition-exchange sorting; in particular, see D.E. Knuth's 109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
111Algorithm Q. 110Algorithm Q.
112.Fn Qsort 111.Fn qsort
113takes O N lg N average time. 112takes O N lg N average time.
114This implementation uses median selection to avoid its 113This implementation uses median selection to avoid its
115O N**2 worst-case behavior. 114O N**2 worst-case behavior.
116.Pp 115.Pp
117The 116The
118.Fn heapsort 117.Fn heapsort
119function is an implementation of J.W.J. William's ``heapsort'' algorithm, 118function is an implementation of J.W.J. William's
119.Dq heapsort
120algorithm,
120a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H. 121a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
121.Fn Heapsort 122.Fn heapsort
122takes O N lg N worst-case time. 123takes O N lg N worst-case time.
123Its 124This implementation of
124.Em only 125.Fn heapsort
125advantage over 126is implemented without recursive function calls.
126.Fn qsort
127is that it uses almost no additional memory; while
128.Fn qsort
129does not allocate memory, it is implemented using recursion.
130.Pp 127.Pp
131The function 128The function
132.Fn mergesort 129.Fn mergesort
133requires additional memory of size 130requires additional memory of size
134.Fa nmemb * 131.Fa nmemb *
135.Fa size 132.Fa size
136bytes; it should be used only when space is not at a premium. 133bytes; it should be used only when space is not at a premium.
137.Fn Mergesort 134.Fn mergesort
138is optimized for data with pre-existing order; its worst case 135is optimized for data with pre-existing order; its worst case
139time is O N lg N; its best case is O N. 136time is O N lg N; its best case is O N.
140.Pp 137.Pp
141Normally, 138Normally,
142.Fn qsort 139.Fn qsort
143is faster than 140is faster than
144.Fn mergesort 141.Fn mergesort ,
145is faster than 142which is faster than
146.Fn heapsort . 143.Fn heapsort .
147Memory availability and pre-existing order in the data can make this 144Memory availability and pre-existing order in the data can make this untrue.
148untrue.
149.Sh RETURN VALUES 145.Sh RETURN VALUES
150The 146The
151.Fn qsort 147.Fn qsort
152function 148function returns no value.
153returns no value.
154.Pp 149.Pp
155Upon successful completion, 150Upon successful completion,
156.Fn heapsort 151.Fn heapsort
@@ -163,30 +158,25 @@ is set to indicate the error.
163.Sh ERRORS 158.Sh ERRORS
164The 159The
165.Fn heapsort 160.Fn heapsort
166function succeeds unless: 161and
162.Fn mergesort
163functions succeed unless:
167.Bl -tag -width Er 164.Bl -tag -width Er
168.It Bq Er EINVAL 165.It Bq Er EINVAL
169The 166The
170.Fa size 167.Fa size
171argument is zero, or, 168argument is zero, or the
172the
173.Fa size 169.Fa size
174argument to 170argument to
175.Fn mergesort 171.Fn mergesort
176is less than 172is less than
177.Dq "sizeof(void *) / 2" . 173.Dq "sizeof(void *) / 2" .
178.It Bq Er ENOMEM 174.It Bq Er ENOMEM
179.Fn Heapsort 175.Fn heapsort
180or 176or
181.Fn mergesort 177.Fn mergesort
182were unable to allocate memory. 178were unable to allocate memory.
183.El 179.El
184.Sh COMPATIBILITY
185Previous versions of
186.Fn qsort
187did not permit the comparison routine itself to call
188.Fn qsort 3 .
189This is no longer true.
190.Sh SEE ALSO 180.Sh SEE ALSO
191.Xr sort 1 , 181.Xr sort 1 ,
192.Xr radixsort 3 182.Xr radixsort 3
@@ -204,7 +194,7 @@ This is no longer true.
204.%T "Heapsort" 194.%T "Heapsort"
205.%J "Communications of the ACM" 195.%J "Communications of the ACM"
206.%V 7:1 196.%V 7:1
207.%P pp. 347-348 197.%P pp. 347\-348
208.Re 198.Re
209.Rs 199.Rs
210.%A Knuth, D.E. 200.%A Knuth, D.E.
@@ -212,23 +202,32 @@ This is no longer true.
212.%B "The Art of Computer Programming" 202.%B "The Art of Computer Programming"
213.%V Vol. 3 203.%V Vol. 3
214.%T "Sorting and Searching" 204.%T "Sorting and Searching"
215.%P pp. 114-123, 145-149 205.%P pp. 114\-123, 145\-149
216.Re 206.Re
217.Rs 207.Rs
218.%A Mcilroy, P.M. 208.%A McIlroy, P.M.
219.%T "Optimistic Sorting and Information Theoretic Complexity" 209.%T "Optimistic Sorting and Information Theoretic Complexity"
220.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms" 210.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
221.%V January 1992 211.%P pp. 467\-464
212.%D January 1993
222.Re 213.Re
223.Rs 214.Rs
224.%A Bentley, J.L. 215.%A Bentley, J.L.
216.%A McIlroy, M.D.
225.%T "Engineering a Sort Function" 217.%T "Engineering a Sort Function"
226.%J "bentley@research.att.com" 218.%J "Software \- Practice and Experience"
227.%V January 1992 219.%V Vol. 23(11)
220.%P pp. 1249\-1265
221.%D November 1993
228.Re 222.Re
229.Sh STANDARDS 223.Sh STANDARDS
224Previous versions of
225.Fn qsort
226did not permit the comparison routine itself to call
227.Fn qsort .
228This is no longer true.
229.Pp
230The 230The
231.Fn qsort 231.Fn qsort
232function 232function conforms to
233conforms to
234.St -ansiC . 233.St -ansiC .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
index c06bd54054..bb4a9a11f2 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.10 2005/08/08 08:05:37 espie 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";*/
36static char *rcsid = "$Id: qsort.c,v 1.1.1.1 1995/10/18 08:42:18 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/types.h> 31#include <sys/types.h>
40#include <stdlib.h> 32#include <stdlib.h>
41 33
42static inline char *med3 __P((char *, char *, char *, int (*)())); 34static __inline char *med3(char *, char *, char *, int (*)(const void *, const void *));
43static inline void swapfunc __P((char *, char *, int, int)); 35static __inline void swapfunc(char *, char *, int, int);
44 36
45#define min(a, b) (a) < (b) ? a : b 37#define min(a, b) (a) < (b) ? a : b
46 38
@@ -49,10 +41,10 @@ static inline void swapfunc __P((char *, char *, int, int));
49 */ 41 */
50#define swapcode(TYPE, parmi, parmj, n) { \ 42#define swapcode(TYPE, parmi, parmj, n) { \
51 long i = (n) / sizeof (TYPE); \ 43 long 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
64static inline void 56static __inline void
65swapfunc(a, b, n, swaptype) 57swapfunc(char *a, char *b, int 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
85static inline char * 75static __inline char *
86med3(a, b, c, cmp) 76med3(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,25 @@ med3(a, b, c, cmp)
93} 81}
94 82
95void 83void
96qsort(a, n, es, cmp) 84qsort(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 d, r, swaptype, swap_cnt;
88 char *a = aa;
103 89
104loop: SWAPINIT(a, es); 90loop: SWAPINIT(a, es);
105 swap_cnt = 0; 91 swap_cnt = 0;
106 if (n < 7) { 92 if (n < 7) {
107 for (pm = a + es; pm < (char *) a + n * es; pm += es) 93 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
108 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 94 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
109 pl -= es) 95 pl -= es)
110 swap(pl, pl - es); 96 swap(pl, pl - es);
111 return; 97 return;
112 } 98 }
113 pm = a + (n / 2) * es; 99 pm = (char *)a + (n / 2) * es;
114 if (n > 7) { 100 if (n > 7) {
115 pl = a; 101 pl = (char *)a;
116 pn = a + (n - 1) * es; 102 pn = (char *)a + (n - 1) * es;
117 if (n > 40) { 103 if (n > 40) {
118 d = (n / 8) * es; 104 d = (n / 8) * es;
119 pl = med3(pl, pl + d, pl + 2 * d, cmp); 105 pl = med3(pl, pl + d, pl + 2 * d, cmp);
@@ -123,9 +109,9 @@ loop: SWAPINIT(a, es);
123 pm = med3(pl, pm, pn, cmp); 109 pm = med3(pl, pm, pn, cmp);
124 } 110 }
125 swap(a, pm); 111 swap(a, pm);
126 pa = pb = a + es; 112 pa = pb = (char *)a + es;
127 113
128 pc = pd = a + (n - 1) * es; 114 pc = pd = (char *)a + (n - 1) * es;
129 for (;;) { 115 for (;;) {
130 while (pb <= pc && (r = cmp(pb, a)) <= 0) { 116 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
131 if (r == 0) { 117 if (r == 0) {
@@ -151,14 +137,14 @@ loop: SWAPINIT(a, es);
151 pc -= es; 137 pc -= es;
152 } 138 }
153 if (swap_cnt == 0) { /* Switch to insertion sort */ 139 if (swap_cnt == 0) { /* Switch to insertion sort */
154 for (pm = a + es; pm < (char *) a + n * es; pm += es) 140 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 141 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es) 142 pl -= es)
157 swap(pl, pl - es); 143 swap(pl, pl - es);
158 return; 144 return;
159 } 145 }
160 146
161 pn = a + n * es; 147 pn = (char *)a + n * es;
162 r = min(pa - (char *)a, pb - pa); 148 r = min(pa - (char *)a, pb - pa);
163 vecswap(a, pb - r, r); 149 vecswap(a, pb - r, r);
164 r = min(pd - pc, pn - pd - es); 150 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..b90a557718 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.11 2007/05/31 19:19:31 jmc 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: May 31 2007 $
36.Dt RADIXSORT 3 31.Dt RADIXSORT 3
37.Os 32.Os
38.Sh NAME 33.Sh NAME
39.Nm radixsort 34.Nm radixsort ,
35.Nm sradixsort
40.Nd radix sort 36.Nd radix sort
41.Sh SYNOPSIS 37.Sh SYNOPSIS
42.Fd #include <limits.h> 38.Fd #include <limits.h>
43.Fd #include <stdlib.h> 39.Fd #include <stdlib.h>
44.Ft int 40.Ft int
45.Fn radixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 41.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
46.Ft int 42.Ft int
47.Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int endbyte" 43.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
48.Sh DESCRIPTION 44.Sh DESCRIPTION
49The 45The
50.Fn radixsort 46.Fn radixsort
51and 47and
52.Fn sradixsort 48.Fn sradixsort
53functions 49functions are implementations of radix sort.
54are implementations of radix sort.
55.Pp 50.Pp
56These functions sort an array of pointers to byte strings, the initial 51These functions sort an array of
57member of which is referenced by 52.Fa nmemb
53pointers to byte strings.
54The initial member is referenced by
58.Fa base . 55.Fa base .
59The byte strings may contain any values; the end of each string 56The byte strings may contain any values; the end of each string
60is denoted by the user-specified value 57is denoted by the user-specified value
@@ -63,26 +60,24 @@ is denoted by the user-specified value
63Applications may specify a sort order by providing the 60Applications may specify a sort order by providing the
64.Fa table 61.Fa table
65argument. 62argument.
66If 63If non-null,
67.Pf non- Dv NULL ,
68.Fa table 64.Fa table
69must reference an array of 65must reference an array of
70.Dv UCHAR_MAX 66.Dv UCHAR_MAX
71+ 1 bytes which contains the sort 67+ 1 bytes which contains the sort weight of each possible byte value.
72weight of each possible byte value.
73The end-of-string byte must have a sort weight of 0 or 255 68The end-of-string byte must have a sort weight of 0 or 255
74(for sorting in reverse order). 69(for sorting in reverse order).
75More than one byte may have the same sort weight. 70More than one byte may have the same sort weight.
76The 71The
77.Fa table 72.Fa table
78argument 73argument is useful for applications which wish to sort different characters
79is useful for applications which wish to sort different characters 74equally; for example, providing a table with the same weights
80equally, for example, providing a table with the same weights 75for A\-Z as for a\-z will result in a case-insensitive sort.
81for A-Z as for a-z will result in a case-insensitive sort.
82If 76If
83.Fa table 77.Fa table
84is NULL, the contents of the array are sorted in ascending order 78is
85according to the 79.Dv NULL ,
80the contents of the array are sorted in ascending order according to the
86.Tn ASCII 81.Tn ASCII
87order of the byte strings they reference and 82order of the byte strings they reference and
88.Fa endbyte 83.Fa endbyte
@@ -90,7 +85,7 @@ has a sorting weight of 0.
90.Pp 85.Pp
91The 86The
92.Fn sradixsort 87.Fn sradixsort
93function is stable, that is, if two elements compare as equal, their 88function is stable; that is, if two elements compare as equal, their
94order in the sorted array is unchanged. 89order in the sorted array is unchanged.
95The 90The
96.Fn sradixsort 91.Fn sradixsort
@@ -107,7 +102,7 @@ particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
107They take linear time relative to the number of bytes in the strings. 102They take linear time relative to the number of bytes in the strings.
108.Sh RETURN VALUES 103.Sh RETURN VALUES
109Upon successful completion 0 is returned. 104Upon successful completion 0 is returned.
110Otherwise, \-1 is returned and the global variable 105Otherwise, \-1 is returned and the global variable
111.Va errno 106.Va errno
112is set to indicate the error. 107is set to indicate the error.
113.Sh ERRORS 108.Sh ERRORS
@@ -122,15 +117,13 @@ is not 0 or 255.
122.Pp 117.Pp
123Additionally, the 118Additionally, the
124.Fn sradixsort 119.Fn sradixsort
125function 120function may fail and set
126may fail and set
127.Va errno 121.Va errno
128for any of the errors specified for the library routine 122for any of the errors specified for the library routine
129.Xr malloc 3 . 123.Xr malloc 3 .
130.Sh SEE ALSO 124.Sh SEE ALSO
131.Xr sort 1 , 125.Xr sort 1 ,
132.Xr qsort 3 126.Xr qsort 3
133.Pp
134.Rs 127.Rs
135.%A Knuth, D.E. 128.%A Knuth, D.E.
136.%D 1968 129.%D 1968
@@ -158,4 +151,5 @@ for any of the errors specified for the library routine
158.Sh HISTORY 151.Sh HISTORY
159The 152The
160.Fn radixsort 153.Fn radixsort
161function first appeared in 4.4BSD. 154function first appeared in
155.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
index dd51013c94..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";*/
39static char *rcsid = "$Id: radixsort.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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
64static inline void simplesort 56static __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);
66static void r_sort_a __P((const u_char **, int, int, const u_char *, u_int)); 58static void r_sort_a(const u_char **, int, int, const u_char *, u_int);
67static void r_sort_b __P((const u_char **, 59static 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
92int 84int
93radixsort(a, n, tab, endch) 85radixsort(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
107int 96int
108sradixsort(a, n, tab, endch) 97sradixsort(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. */
135void 121void
136r_sort_a(a, n, i, tr, endch) 122r_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. */
226void 208void
227r_sort_b(a, ta, n, i, tr, endch) 209r_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
298static inline void 277static __inline void
299simplesort(a, n, b, tr, endch) /* insertion sort */ 278simplesort(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..df4feaacdb 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,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: @(#)rand.3 6.7 (Berkeley) 6/29/91 32.\" $OpenBSD: rand.3,v 1.10 2007/05/31 19:19:31 jmc 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: May 31 2007 $
40.Dt RAND 3 35.Dt RAND 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -46,12 +41,15 @@
46.Sh SYNOPSIS 41.Sh SYNOPSIS
47.Fd #include <stdlib.h> 42.Fd #include <stdlib.h>
48.Ft void 43.Ft void
49.Fn srand "unsigned seed" 44.Fn srand "unsigned int seed"
50.Ft int 45.Ft int
51.Fn rand void 46.Fn rand void
47.Ft int
48.Fn rand_r "unsigned int *seed"
52.Sh DESCRIPTION 49.Sh DESCRIPTION
53.Bf -symbolic 50.Bf -symbolic
54These interfaces are obsoleted by random(3). 51These interfaces are obsoleted by
52.Xr random 3 .
55.Ef 53.Ef
56.Pp 54.Pp
57The 55The
@@ -73,13 +71,28 @@ with the same seed value.
73.Pp 71.Pp
74If no seed value is provided, the functions are automatically 72If no seed value is provided, the functions are automatically
75seeded with a value of 1. 73seeded with a value of 1.
74.Pp
75The
76.Fn rand_r
77is a thread-safe version of
78.Fn rand .
79Storage for the seed must be provided through the
80.Fa seed
81argument, and needs to have been initialized by the caller.
76.Sh SEE ALSO 82.Sh SEE ALSO
83.Xr arc4random 3 ,
84.Xr rand48 3 ,
77.Xr random 3 85.Xr random 3
78.Sh STANDARDS 86.Sh STANDARDS
79The 87The
80.Fn rand 88.Fn rand
81and 89and
82.Fn srand 90.Fn srand
83functions 91functions conform to
84conform to
85.St -ansiC . 92.St -ansiC .
93.Pp
94The
95.Fn rand_r
96function conforms to ISO/IEC 9945-1 ANSI/IEEE
97.Pq Dq Tn POSIX
98Std 1003.1c Draft 10.
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
index 361d473448..0f9c100807 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,26 @@
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";*/
36static char *rcsid = "$Id: rand.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/types.h> 30#include <sys/types.h>
40#include <stdlib.h> 31#include <stdlib.h>
41 32
42static u_long next = 1; 33static u_int next = 1;
34
35int
36rand_r(u_int *seed)
37{
38 *seed = *seed * 1103515245 + 12345;
39 return (*seed % ((u_int)RAND_MAX + 1));
40}
43 41
44int 42int
45rand() 43rand(void)
46{ 44{
47 return ((next = next * 1103515245 + 12345) % ((u_int)RAND_MAX + 1)); 45 return (rand_r(&next));
48} 46}
49 47
50void 48void
51srand(seed) 49srand(u_int seed)
52u_int seed;
53{ 50{
54 next = seed; 51 next = seed;
55} 52}
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
index 5a772c9a8c..0e8ca5389b 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.11 2007/05/31 19:19:31 jmc Exp $
13.\" 13.\"
14.Dd October 8, 1993 14.Dd $Mdocdate: May 31 2007 $
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.Fd #include <stdlib.h>
30.Ft double 30.Ft double
31.Fn drand48 void 31.Fn drand48 void
32.Ft double 32.Ft double
33.Fn erand48 "unsigned short xseed[3]" 33.Fn erand48 "unsigned short xseed[3]"
@@ -49,12 +49,13 @@
49The 49The
50.Fn rand48 50.Fn rand48
51family of functions generates pseudo-random numbers using a linear 51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size. The 52congruential algorithm working on integers 48 bits in size.
53particular formula employed is 53The particular formula employed is
54r(n+1) = (a * r(n) + c) mod m 54r(n+1) = (a * r(n) + c) mod m
55where the default values are 55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and 56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11. The modulus is always fixed at m = 2 ** 48. 57the addend c = 0xb = 11.
58The modulus is always fixed at m = 2 ** 48.
58r(n) is called the seed of the random number generator. 59r(n) is called the seed of the random number generator.
59.Pp 60.Pp
60For all the six generator routines described next, the first 61For all the six generator routines described next, the first
@@ -63,15 +64,17 @@ computational step is to perform a single iteration of the algorithm.
63.Fn drand48 64.Fn drand48
64and 65and
65.Fn erand48 66.Fn erand48
66return values of type double. The full 48 bits of r(n+1) are 67return values of type double.
68The full 48 bits of r(n+1) are
67loaded into the mantissa of the returned value, with the exponent set 69loaded into the mantissa of the returned value, with the exponent set
68such that the values produced lie in the interval [0.0, 1.0). 70such that the values produced lie in the interval [0.0, 1.0].
69.Pp 71.Pp
70.Fn lrand48 72.Fn lrand48
71and 73and
72.Fn nrand48 74.Fn nrand48
73return values of type long in the range 75return values of type long in the range
74[0, 2**31-1]. The high-order (31) bits of 76[0, 2**31-1].
77The high-order (31) bits of
75r(n+1) are loaded into the lower bits of the returned value, with 78r(n+1) are loaded into the lower bits of the returned value, with
76the topmost (sign) bit set to zero. 79the topmost (sign) bit set to zero.
77.Pp 80.Pp
@@ -79,14 +82,15 @@ the topmost (sign) bit set to zero.
79and 82and
80.Fn jrand48 83.Fn jrand48
81return values of type long in the range 84return values of type long in the range
82[-2**31, 2**31-1]. The high-order (32) bits of 85[-2**31, 2**31-1].
83r(n+1) are loaded into the returned value. 86The high-order (32) bits of r(n+1) are loaded into the returned value.
84.Pp 87.Pp
85.Fn drand48 , 88.Fn drand48 ,
86.Fn lrand48 , 89.Fn lrand48 ,
87and 90and
88.Fn mrand48 91.Fn mrand48
89use an internal buffer to store r(n). For these functions 92use an internal buffer to store r(n).
93For these functions
90the initial value of r(0) = 0x1234abcd330e = 20017429951246. 94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
91.Pp 95.Pp
92On the other hand, 96On the other hand,
@@ -118,12 +122,12 @@ also initializes the internal buffer r(n) of
118and 122and
119.Fn mrand48 , 123.Fn mrand48 ,
120but here all 48 bits of the seed can be specified in an array of 3 shorts, 124but here all 48 bits of the seed can be specified in an array of 3 shorts,
121where the zeroth member specifies the lowest bits. Again, 125where the zeroth member specifies the lowest bits.
122the constant multiplicand and addend of the algorithm are 126Again, the constant multiplicand and addend of the algorithm are
123reset to the default values given above. 127reset to the default values given above.
124.Fn seed48 128.Fn seed48
125returns a pointer to an array of 3 shorts which contains the old seed. 129returns a pointer to an array of 3 shorts which contains the old seed.
126This array is statically allocated, thus its contents are lost after 130This array is statically allocated, so its contents are lost after
127each new call to 131each new call to
128.Fn seed48 . 132.Fn seed48 .
129.Pp 133.Pp
@@ -152,9 +156,10 @@ always also set the multiplicand and addend for any of the six
152generator calls. 156generator calls.
153.Pp 157.Pp
154For a more powerful random number generator, see 158For a more powerful random number generator, see
155.Xr random 3 159.Xr random 3 .
156.Sh AUTHOR
157Martin Birgmeier
158.Sh SEE ALSO 160.Sh SEE ALSO
161.Xr arc4random 3 ,
159.Xr rand 3 , 162.Xr rand 3 ,
160.Xr random 3 . 163.Xr random 3
164.Sh AUTHORS
165Martin Birgmeier
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
index 12496d1c8c..afa49f65f3 100644
--- a/src/lib/libc/stdlib/rand48.h
+++ b/src/lib/libc/stdlib/rand48.h
@@ -9,6 +9,8 @@
9 * This software is provided ``as is'', and comes with no warranties 9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens 10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software. 11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
12 */ 14 */
13 15
14#ifndef _RAND48_H_ 16#ifndef _RAND48_H_
@@ -17,7 +19,7 @@
17#include <math.h> 19#include <math.h>
18#include <stdlib.h> 20#include <stdlib.h>
19 21
20void __dorand48 __P((unsigned short[3])); 22void __dorand48(unsigned short[3]);
21 23
22#define RAND48_SEED_0 (0x330e) 24#define RAND48_SEED_0 (0x330e)
23#define RAND48_SEED_1 (0xabcd) 25#define RAND48_SEED_1 (0xabcd)
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
index 38c15a9803..ed05df162b 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.19 2007/05/31 19:19:31 jmc 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: May 31 2007 $
36.Dt RANDOM 3 31.Dt RANDOM 3
37.Os BSD 4.2 32.Os
38.Sh NAME 33.Sh NAME
39.Nm random , 34.Nm random ,
40.Nm srandom , 35.Nm srandom ,
36.Nm srandomdev ,
41.Nm initstate , 37.Nm initstate ,
42.Nm setstate 38.Nm setstate
43.Nd better random number generator; routines for changing generators 39.Nd better random number generator; routines for changing generators
44.Sh SYNOPSIS 40.Sh SYNOPSIS
45.Fd #include <stdlib.h> 41.Fd #include <stdlib.h>
46.Ft long 42.Ft long
47.Fn random void 43.Fn random void
48.Ft void 44.Ft void
49.Fn srandom "unsigned seed" 45.Fn srandom "unsigned int seed"
46.Ft void
47.Fn srandomdev void
50.Ft char * 48.Ft char *
51.Fn initstate "unsigned seed" "char *state" "int n" 49.Fn initstate "unsigned int seed" "char *state" "size_t n"
52.Ft char * 50.Ft char *
53.Fn setstate "char *state" 51.Fn setstate "const char *state"
54.Sh DESCRIPTION 52.Sh DESCRIPTION
55The 53The
56.Fn random 54.Fn random
57function 55function uses a non-linear additive feedback random number generator employing
58uses a non-linear additive feedback random number generator employing a 56a default table of size 31 long integers to return successive pseudo-random
59default table of size 31 long integers to return successive pseudo-random 57numbers in the range from 0 to (2**31)\-1.
60numbers in the range from 0 to
61.if t 2\u\s731\s10\d\(mi1.
62.if n (2**31)\(mi1.
63The period of this random number generator is very large, approximately 58The period of this random number generator is very large, approximately
64.if t 16\(mu(2\u\s731\s10\d\(mi1). 5916*((2**31)\-1).
65.if n 16*((2**31)\(mi1).
66.Pp 60.Pp
67The 61The
68.Fn random Ns / Fn srandom 62.Fn random
69have (almost) the same calling sequence and initialization properties as 63and
70.Xr rand 3 Ns / Xr srand 3 . 64.Fn srandom
65functions have (almost) the same calling sequence and initialization
66properties as
67.Xr rand 3 Ns / Ns Xr srand 3 .
71The difference is that 68The difference is that
72.Xr rand 69.Xr rand
73produces a much less random sequence \(em in fact, the low dozen bits 70produces a much less random sequence \(em in fact, the low dozen bits
74generated by rand go through a cyclic pattern. All the bits generated by 71generated by rand go through a cyclic pattern.
72All the bits generated by
75.Fn random 73.Fn random
76are usable. For example, 74are usable.
75For example,
77.Sq Li random()&01 76.Sq Li random()&01
78will produce a random binary 77will produce a random binary
79value. 78value.
80.Pp 79.Pp
81Unlike 80Like
82.Xr srand ,
83.Fn srandom
84does not return the old seed; the reason for this is that the amount of
85state information used is much more than a single word. (Two other
86routines are provided to deal with restarting/changing random
87number generators). Like
88.Xr rand 3 , 81.Xr rand 3 ,
89however,
90.Fn random 82.Fn random
91will by default produce a sequence of numbers that can be duplicated 83will by default produce a sequence of numbers that can be duplicated
92by calling 84by calling
93.Fn srandom 85.Fn srandom
94with 86with
95.Ql 1 87.Ql 1
96as the seed. 88as the seed.
97.Pp 89.Pp
98The 90The
91.Fn srandomdev
92routine initializes a state array using
93random numbers obtained from the kernel,
94suitable for cryptographic use.
95Note that this particular seeding procedure can generate
96states which are impossible to reproduce by calling
97.Fn srandom
98with any value, since the succeeding terms in the
99state buffer are no longer derived from the LC algorithm applied to
100a fixed seed.
101.Pp
102The
99.Fn initstate 103.Fn initstate
100routine allows a state array, passed in as an argument, to be initialized 104routine allows a state array, passed in as an argument, to be initialized
101for future use. The size of the state array (in bytes) is used by 105for future use.
106The size of the state array (in bytes) is used by
102.Fn initstate 107.Fn initstate
103to decide how sophisticated a random number generator it should use \(em the 108to decide how sophisticated a random number generator it should use \(em the
104more state, the better the random numbers will be. 109more 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
1068, 32, 64, 128, and 256 bytes; other amounts will be rounded down to 1118, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
107the nearest known amount. Using less than 8 bytes will cause an error.) 112the nearest known amount.
113Using less than 8 bytes will cause an error.)
108The seed for the initialization (which specifies a starting point for 114The seed for the initialization (which specifies a starting point for
109the random number sequence, and provides for restarting at the same 115the random number sequence, and provides for restarting at the same
110point) is also an argument. 116point) is also an argument.
111The 117The
112.Fn initstate 118.Fn initstate
113function 119function returns a pointer to the previous state information array.
114returns a pointer to the previous state information array.
115.Pp 120.Pp
116Once a state has been initialized, the 121Once a state has been initialized, the
117.Fn setstate 122.Fn setstate
118routine provides for rapid switching between states. 123routine provides for rapid switching between states.
119The 124The
120.Fn setstate 125.Fn setstate
121function 126function returns a pointer to the previous state array; its
122returns a pointer to the previous state array; its
123argument state array is used for further random number generation 127argument state array is used for further random number generation
124until the next call to 128until 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
143it is initialized. 147it is initialized.
144.Pp 148.Pp
145With 256 bytes of state information, the period of the random number 149With 256 bytes of state information, the period of the random number
146generator is greater than 150generator is greater than 2**69
147.if t 2\u\s769\s10\d,
148.if n 2**69
149which should be sufficient for most purposes. 151which should be sufficient for most purposes.
150.Sh AUTHOR
151Earl T. Cohen
152.Sh DIAGNOSTICS 152.Sh DIAGNOSTICS
153If 153If
154.Fn initstate 154.Fn initstate
@@ -157,11 +157,29 @@ is called with less than 8 bytes of state information, or if
157detects that the state information has been garbled, error 157detects that the state information has been garbled, error
158messages are printed on the standard error output. 158messages 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
165The
166.Fn random ,
167.Fn srandom ,
168.Fn initstate ,
169and
170.Fn setstate
171functions conform to
172.St -xpg4.2 .
173.Pp
174The
175.Fn srandomdev
176function is an extension.
161.Sh HISTORY 177.Sh HISTORY
162These 178These
163functions appeared in 179functions appeared in
164.Bx 4.2 . 180.Bx 4.2 .
181.Sh AUTHORS
182.An Earl T. Cohen
165.Sh BUGS 183.Sh BUGS
166About 2/3 the speed of 184About 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..48e892042b 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.15 2005/11/30 07:51:02 otto 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,13 @@
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>
36static 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>
41 38
42/* 39/*
43 * random.c: 40 * random.c:
@@ -55,10 +52,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 52 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 53 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 54 *
58 * Internally, the state information is treated as an array of longs; the 55 * 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 56 * 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 57 * 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 58 * 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: 59 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 60 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 61 * stored in it -- see setstate() for details).
@@ -134,14 +131,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. 131 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 132 */
136 133
137static long randtbl[DEG_3 + 1] = { 134static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 135 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 136 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 137 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 138 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 139 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 140 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 141 0xf3bec5da,
145}; 142};
146 143
147/* 144/*
@@ -158,8 +155,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 155 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 156 * to point to randtbl[1] (as explained below).
160 */ 157 */
161static long *fptr = &randtbl[SEP_3 + 1]; 158static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 159static int32_t *rptr = &randtbl[1];
163 160
164/* 161/*
165 * The following things are the pointer to the state information table, the 162 * The following things are the pointer to the state information table, the
@@ -171,11 +168,11 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 168 * 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. 169 * the last element to see if the front and rear pointers have wrapped.
173 */ 170 */
174static long *state = &randtbl[1]; 171static int32_t *state = &randtbl[1];
172static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 173static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 174static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 175static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1];
179 176
180/* 177/*
181 * srandom: 178 * srandom:
@@ -190,18 +187,28 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
190 * for default usage relies on values produced by this routine. 187 * for default usage relies on values produced by this routine.
191 */ 188 */
192void 189void
193srandom(x) 190srandom(unsigned int x)
194 u_int x;
195{ 191{
196 register int i, j; 192 int i;
193 int32_t test;
194 div_t val;
197 195
198 if (rand_type == TYPE_0) 196 if (rand_type == TYPE_0)
199 state[0] = x; 197 state[0] = x;
200 else { 198 else {
201 j = 1;
202 state[0] = x; 199 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 200 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 201 /*
202 * Implement the following, without overflowing 31 bits:
203 *
204 * state[i] = (16807 * state[i - 1]) % 2147483647;
205 *
206 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
207 */
208 val = div(state[i-1], 127773);
209 test = 16807 * val.rem - 2836 * val.quot;
210 state[i] = test + (test < 0 ? 2147483647 : 0);
211 }
205 fptr = &state[rand_sep]; 212 fptr = &state[rand_sep];
206 rptr = &state[0]; 213 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 214 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +217,38 @@ srandom(x)
210} 217}
211 218
212/* 219/*
220 * srandomdev:
221 *
222 * Many programs choose the seed value in a totally predictable manner.
223 * This often causes problems. We seed the generator using random
224 * data from the kernel.
225 * Note that this particular seeding procedure can generate states
226 * which are impossible to reproduce by calling srandom() with any
227 * value, since the succeeding terms in the state buffer are no longer
228 * derived from the LC algorithm applied to a fixed seed.
229 */
230void
231srandomdev(void)
232{
233 int mib[2];
234 size_t len;
235
236 if (rand_type == TYPE_0)
237 len = sizeof(state[0]);
238 else
239 len = rand_deg * sizeof(state[0]);
240
241 mib[0] = CTL_KERN;
242 mib[1] = KERN_ARND;
243 sysctl(mib, 2, state, &len, NULL, 0);
244
245 if (rand_type != TYPE_0) {
246 fptr = &state[rand_sep];
247 rptr = &state[0];
248 }
249}
250
251/*
213 * initstate: 252 * initstate:
214 * 253 *
215 * Initialize the state information in the given array of n bytes for future 254 * Initialize the state information in the given array of n bytes for future
@@ -229,22 +268,16 @@ srandom(x)
229 * Returns a pointer to the old state. 268 * Returns a pointer to the old state.
230 */ 269 */
231char * 270char *
232initstate(seed, arg_state, n) 271initstate(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{ 272{
237 register char *ostate = (char *)(&state[-1]); 273 char *ostate = (char *)(&state[-1]);
238 274
239 if (rand_type == TYPE_0) 275 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 276 state[-1] = rand_type;
241 else 277 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 278 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 279 if (n < BREAK_0)
244 (void)fprintf(stderr, 280 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 281 if (n < BREAK_1) {
249 rand_type = TYPE_0; 282 rand_type = TYPE_0;
250 rand_deg = DEG_0; 283 rand_deg = DEG_0;
@@ -266,7 +299,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 299 rand_deg = DEG_4;
267 rand_sep = SEP_4; 300 rand_sep = SEP_4;
268 } 301 }
269 state = &(((long *)arg_state)[1]); /* first location */ 302 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 303 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 304 srandom(seed);
272 if (rand_type == TYPE_0) 305 if (rand_type == TYPE_0)
@@ -292,12 +325,11 @@ initstate(seed, arg_state, n)
292 * Returns a pointer to the old state information. 325 * Returns a pointer to the old state information.
293 */ 326 */
294char * 327char *
295setstate(arg_state) 328setstate(const char *arg_state)
296 char *arg_state;
297{ 329{
298 register long *new_state = (long *)arg_state; 330 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 331 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 332 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 333 char *ostate = (char *)(&state[-1]);
302 334
303 if (rand_type == TYPE_0) 335 if (rand_type == TYPE_0)
@@ -315,8 +347,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 347 rand_sep = seps[type];
316 break; 348 break;
317 default: 349 default:
318 (void)fprintf(stderr, 350 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 351 }
321 state = &new_state[1]; 352 state = &new_state[1];
322 if (rand_type != TYPE_0) { 353 if (rand_type != TYPE_0) {
@@ -345,9 +376,9 @@ setstate(arg_state)
345 * Returns a 31-bit random number. 376 * Returns a 31-bit random number.
346 */ 377 */
347long 378long
348random() 379random(void)
349{ 380{
350 long i; 381 int32_t i;
351 382
352 if (rand_type == TYPE_0) 383 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 384 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +391,5 @@ random()
360 } else if (++rptr >= end_ptr) 391 } else if (++rptr >= end_ptr)
361 rptr = state; 392 rptr = state;
362 } 393 }
363 return(i); 394 return((long)i);
364} 395}
diff --git a/src/lib/libc/stdlib/realloc.3 b/src/lib/libc/stdlib/realloc.3
deleted file mode 100644
index 66f09b2081..0000000000
--- a/src/lib/libc/stdlib/realloc.3
+++ /dev/null
@@ -1,100 +0,0 @@
1.\" Copyright (c) 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" from: @(#)realloc.3 5.1 (Berkeley) 5/2/91
33.\" $Id: realloc.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
34.\"
35.Dd May 2, 1991
36.Dt REALLOC 3
37.Os
38.Sh NAME
39.Nm realloc
40.Nd reallocation of memory function
41.Sh SYNOPSIS
42.Fd #include <stdlib.h>
43.Ft void *
44.Fn realloc "void *ptr" "size_t size"
45.Sh DESCRIPTION
46The
47.Fn realloc
48function changes the size of the object pointed to by
49.Fa ptr
50to the size specified by
51.Fa size .
52The contents of the object are unchanged up to the lesser
53of the new and old sizes.
54If the new size is larger, the value of the newly allocated portion
55of the object is indeterminate.
56If
57.Fa ptr
58is a null pointer, the
59.Fn realloc
60function behaves like the
61.Xr malloc 3
62function for the specified size.
63Otherwise, if
64.Fa ptr
65does not match a pointer earlier returned by the
66.Xr calloc 3 ,
67.Xr malloc 3 ,
68or
69.Fn realloc
70function, or if the space has been deallocated
71by a call to the
72.Xr free
73or
74.Fn realloc
75function, unpredictable and usually detrimental
76behavior will occur.
77If the space cannot be allocated, the object
78pointed to by
79.Fa ptr
80is unchanged.
81If
82.Fa size
83is zero and
84.Fa ptr
85is not a null pointer, the object it points to is freed.
86.Pp
87The
88.Fn realloc
89function returns either a null pointer or a pointer
90to the possibly moved allocated space.
91.Sh SEE ALSO
92.Xr alloca 3 ,
93.Xr calloc 3 ,
94.Xr free 3 ,
95.Xr malloc 3 ,
96.Sh STANDARDS
97The
98.Fn realloc
99function conforms to
100.St -ansiC .
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
index 9d8b1ff2ce..c64fc3d637 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.15 2007/07/06 15:42:04 millert Exp $
36.\" $Id: realpath.3,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $
37.\" 32.\"
38.Dd "February 16, 1994" 33.Dd $Mdocdate: July 6 2007 $
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.Fd #include <limits.h>
46.Fd #include <stdlib.h> 41.Fd #include <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[PATH_MAX]"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn realpath 46.Fn realpath
@@ -57,18 +52,17 @@ and
57.Pa /../ 52.Pa /../
58in 53in
59.Fa pathname , 54.Fa pathname ,
60and copies the resulting absolute pathname into 55and copies the resulting absolute pathname into the memory referenced by
61the memory referenced by 56.Fa resolved .
62.Fa resolvedname .
63The 57The
64.Fa resolvedname 58.Fa resolved
65argument 59argument
66.Em must 60.Em must
67refer to a buffer capable of storing at least 61refer to a buffer capable of storing at least
68.Dv MAXPATHLEN 62.Dv PATH_MAX
69characters. 63characters.
70.Pp 64.Pp
71The 65The
72.Fn realpath 66.Fn realpath
73function will resolve both absolute and relative paths 67function will resolve both absolute and relative paths
74and return the absolute pathname corresponding to 68and return the absolute pathname corresponding to
@@ -78,33 +72,37 @@ All but the last component of
78must exist when 72must exist when
79.Fn realpath 73.Fn realpath
80is called. 74is called.
81.Sh "RETURN VALUES" 75.Sh RETURN VALUES
82The 76The
83.Fn realpath 77.Fn realpath
84function returns 78function returns
85.Fa resolved_name 79.Fa resolved
86on success. 80on success.
87If an error occurs, 81If an error occurs,
88.Fn realpath 82.Fn realpath
89returns 83returns
90.Dv NULL , 84.Dv NULL
91and 85and the contents of
92.Fa resolved_name 86.Fa resolved
93contains the pathname which caused the problem. 87are undefined.
94.Sh ERRORS 88.Sh ERRORS
95The function 89The function
96.Fn realpath 90.Fn realpath
97may fail and set the external variable 91may fail and set the external variable
98.Va errno 92.Va errno
99for any of the errors specified for the library functions 93for 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 , 94.Xr lstat 2 ,
104.Xr open 2 , 95.Xr readlink 2 ,
105.Xr readlink 2
106and 96and
107.Xr getcwd 3 . 97.Xr getcwd 3 .
98.Sh SEE ALSO
99.Xr readlink 1 ,
100.Xr getcwd 3
101.Sh HISTORY
102The
103.Fn realpath
104function call first appeared in
105.Bx 4.4 .
108.Sh CAVEATS 106.Sh CAVEATS
109This implementation of 107This implementation of
110.Fn realpath 108.Fn realpath
@@ -114,13 +112,6 @@ The
114version always returns absolute pathnames, 112version always returns absolute pathnames,
115whereas the Solaris implementation will, 113whereas the Solaris implementation will,
116under certain circumstances, return a relative 114under certain circumstances, return a relative
117.Fa resolved_path 115.Fa resolved
118when given a relative 116when given a relative
119.Fa pathname . 117.Fa pathname .
120.Sh "SEE ALSO"
121.Xr getcwd 3
122.Sh HISTORY
123The
124.Fn realpath
125function call first appeared in
126.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index e349b7e068..4cb847b313 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.13 2005/08/08 08:05:37 espie 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,164 @@
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";*/
39static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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
51/* 38/*
52 * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); 39 * char *realpath(const char *path, char resolved[PATH_MAX]);
53 * 40 *
54 * Find the real name of path, by removing all ".", ".." and symlink 41 * Find the real name of path, by removing all ".", ".." and symlink
55 * components. Returns (resolved) on success, or (NULL) on failure, 42 * components. Returns (resolved) on success, or (NULL) on failure,
56 * in which case the path which caused trouble is left in (resolved). 43 * in which case the path which caused trouble is left in (resolved).
57 */ 44 */
58char * 45char *
59realpath(path, resolved) 46realpath(const char *path, char resolved[PATH_MAX])
60 const char *path;
61 char *resolved;
62{ 47{
63 struct stat sb; 48 struct stat sb;
64 int fd, n, rootd, serrno; 49 char *p, *q, *s;
65 char *p, *q, wbuf[MAXPATHLEN]; 50 size_t left_len, resolved_len;
51 unsigned symlinks;
52 int serrno, slen;
53 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
66 54
67 /* Save the starting point. */ 55 serrno = errno;
68 if ((fd = open(".", O_RDONLY)) < 0) { 56 symlinks = 0;
69 (void)strcpy(resolved, "."); 57 if (path[0] == '/') {
58 resolved[0] = '/';
59 resolved[1] = '\0';
60 if (path[1] == '\0')
61 return (resolved);
62 resolved_len = 1;
63 left_len = strlcpy(left, path + 1, sizeof(left));
64 } else {
65 if (getcwd(resolved, PATH_MAX) == NULL) {
66 strlcpy(resolved, ".", PATH_MAX);
67 return (NULL);
68 }
69 resolved_len = strlen(resolved);
70 left_len = strlcpy(left, path, sizeof(left));
71 }
72 if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
73 errno = ENAMETOOLONG;
70 return (NULL); 74 return (NULL);
71 } 75 }
72 76
73 /* 77 /*
74 * Find the dirname and basename from the path to be resolved. 78 * Iterate over path components in `left'.
75 * Change directory to the dirname component.
76 * lstat the basename part.
77 * if it is a symlink, read in the value and loop.
78 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename.
80 */ 79 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1); 80 while (left_len != 0) {
82 resolved[MAXPATHLEN - 1] = '\0'; 81 /*
83loop: 82 * Extract the next path component and adjust `left'
84 q = strrchr(resolved, '/'); 83 * and its length.
85 if (q != NULL) { 84 */
86 p = q + 1; 85 p = strchr(left, '/');
87 if (q == resolved) 86 s = p ? p : left + left_len;
88 q = "/"; 87 if (s - left >= sizeof(next_token)) {
89 else { 88 errno = ENAMETOOLONG;
90 do { 89 return (NULL);
91 --q;
92 } while (q > resolved && *q == '/');
93 q[1] = '\0';
94 q = resolved;
95 } 90 }
96 if (chdir(q) < 0) 91 memcpy(next_token, left, s - left);
97 goto err1; 92 next_token[s - left] = '\0';
98 } else 93 left_len -= s - left;
99 p = resolved; 94 if (p != NULL)
100 95 memmove(left, s + 1, left_len + 1);
101 /* Deal with the last component. */ 96 if (resolved[resolved_len - 1] != '/') {
102 if (lstat(p, &sb) == 0) { 97 if (resolved_len + 1 >= PATH_MAX) {
103 if (S_ISLNK(sb.st_mode)) { 98 errno = ENAMETOOLONG;
104 n = readlink(p, resolved, MAXPATHLEN); 99 return (NULL);
105 if (n < 0) 100 }
106 goto err1; 101 resolved[resolved_len++] = '/';
107 resolved[n] = '\0'; 102 resolved[resolved_len] = '\0';
108 goto loop;
109 } 103 }
110 if (S_ISDIR(sb.st_mode)) { 104 if (next_token[0] == '\0')
111 if (chdir(p) < 0) 105 continue;
112 goto err1; 106 else if (strcmp(next_token, ".") == 0)
113 p = ""; 107 continue;
108 else if (strcmp(next_token, "..") == 0) {
109 /*
110 * Strip the last path component except when we have
111 * single "/"
112 */
113 if (resolved_len > 1) {
114 resolved[resolved_len - 1] = '\0';
115 q = strrchr(resolved, '/') + 1;
116 *q = '\0';
117 resolved_len = q - resolved;
118 }
119 continue;
114 } 120 }
115 }
116
117 /*
118 * Save the last component name and get the full pathname of
119 * the current directory.
120 */
121 (void)strcpy(wbuf, p);
122 if (getcwd(resolved, MAXPATHLEN) == 0)
123 goto err1;
124 121
125 /* 122 /*
126 * Join the two strings together, ensuring that the right thing 123 * Append the next path component and lstat() it. If
127 * happens if the last component is empty, or the dirname is root. 124 * lstat() fails we still can return successfully if
128 */ 125 * there are no more path components left.
129 if (resolved[0] == '/' && resolved[1] == '\0') 126 */
130 rootd = 1; 127 resolved_len = strlcat(resolved, next_token, PATH_MAX);
131 else 128 if (resolved_len >= PATH_MAX) {
132 rootd = 0;
133
134 if (*wbuf) {
135 if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) {
136 errno = ENAMETOOLONG; 129 errno = ENAMETOOLONG;
137 goto err1; 130 return (NULL);
138 } 131 }
139 if (rootd == 0) 132 if (lstat(resolved, &sb) != 0) {
140 (void)strcat(resolved, "/"); 133 if (errno == ENOENT && p == NULL) {
141 (void)strcat(resolved, wbuf); 134 errno = serrno;
142 } 135 return (resolved);
136 }
137 return (NULL);
138 }
139 if (S_ISLNK(sb.st_mode)) {
140 if (symlinks++ > MAXSYMLINKS) {
141 errno = ELOOP;
142 return (NULL);
143 }
144 slen = readlink(resolved, symlink, sizeof(symlink) - 1);
145 if (slen < 0)
146 return (NULL);
147 symlink[slen] = '\0';
148 if (symlink[0] == '/') {
149 resolved[1] = 0;
150 resolved_len = 1;
151 } else if (resolved_len > 1) {
152 /* Strip the last path component. */
153 resolved[resolved_len - 1] = '\0';
154 q = strrchr(resolved, '/') + 1;
155 *q = '\0';
156 resolved_len = q - resolved;
157 }
143 158
144 /* Go back to where we came from. */ 159 /*
145 if (fchdir(fd) < 0) { 160 * If there are any path components left, then
146 serrno = errno; 161 * append them to symlink. The result is placed
147 goto err2; 162 * in `left'.
163 */
164 if (p != NULL) {
165 if (symlink[slen - 1] != '/') {
166 if (slen + 1 >= sizeof(symlink)) {
167 errno = ENAMETOOLONG;
168 return (NULL);
169 }
170 symlink[slen] = '/';
171 symlink[slen + 1] = 0;
172 }
173 left_len = strlcat(symlink, left, sizeof(left));
174 if (left_len >= sizeof(left)) {
175 errno = ENAMETOOLONG;
176 return (NULL);
177 }
178 }
179 left_len = strlcpy(left, symlink, sizeof(left));
180 }
148 } 181 }
149 182
150 /* It's okay if the close fails, what's an fd more or less? */ 183 /*
151 (void)close(fd); 184 * Remove trailing slash except when the resolved pathname
185 * is a single "/".
186 */
187 if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
188 resolved[resolved_len - 1] = '\0';
152 return (resolved); 189 return (resolved);
153
154err1: serrno = errno;
155 (void)fchdir(fd);
156err2: (void)close(fd);
157 errno = serrno;
158 return (NULL);
159} 190}
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
33struct qelem {
34 struct qelem *q_forw;
35 struct qelem *q_back;
36};
37
38void
39remque(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..36540ebb0c 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.9 2005/08/08 08:05:37 espie 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,30 +28,24 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/
36static char *rcsid = "$Id: setenv.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <stdlib.h> 31#include <stdlib.h>
40#include <string.h> 32#include <string.h>
41 33
34char *__findenv(const char *name, int *offset);
35
36extern char **environ;
37
42/* 38/*
43 * setenv -- 39 * setenv --
44 * Set the value of the environmental variable "name" to be 40 * Set the value of the environmental variable "name" to be
45 * "value". If rewrite is set, replace any current value. 41 * "value". If rewrite is set, replace any current value.
46 */ 42 */
47int 43int
48setenv(name, value, rewrite) 44setenv(const char *name, const char *value, int rewrite)
49 register const char *name;
50 register const char *value;
51 int rewrite;
52{ 45{
53 extern char **environ; 46 static char **lastenv; /* last value of environ */
54 static int alloced; /* if allocated space before */ 47 char *C;
55 register char *C;
56 int l_value, offset; 48 int l_value, offset;
57 char *__findenv();
58 49
59 if (*value == '=') /* no `=' in value */ 50 if (*value == '=') /* no `=' in value */
60 ++value; 51 ++value;
@@ -63,39 +54,34 @@ setenv(name, value, rewrite)
63 if (!rewrite) 54 if (!rewrite)
64 return (0); 55 return (0);
65 if (strlen(C) >= l_value) { /* old larger; copy over */ 56 if (strlen(C) >= l_value) { /* old larger; copy over */
66 while (*C++ = *value++); 57 while ((*C++ = *value++))
58 ;
67 return (0); 59 return (0);
68 } 60 }
69 } else { /* create new slot */ 61 } else { /* create new slot */
70 register int cnt; 62 size_t cnt;
71 register char **P; 63 char **P;
72 64
73 for (P = environ, cnt = 0; *P; ++P, ++cnt); 65 for (P = environ; *P != NULL; P++)
74 if (alloced) { /* just increase size */ 66 ;
75 environ = (char **)realloc((char *)environ, 67 cnt = P - environ;
76 (size_t)(sizeof(char *) * (cnt + 2))); 68 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
77 if (!environ) 69 if (!P)
78 return (-1); 70 return (-1);
79 } 71 if (lastenv != environ)
80 else { /* get new space */ 72 memcpy(P, environ, cnt * sizeof(char *));
81 alloced = 1; /* copy old entries into it */ 73 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; 74 offset = cnt;
75 environ[cnt + 1] = NULL;
91 } 76 }
92 for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ 77 for (C = (char *)name; *C && *C != '='; ++C)
78 ; /* no `=' in name */
93 if (!(environ[offset] = /* name + `=' + value */ 79 if (!(environ[offset] = /* name + `=' + value */
94 malloc((size_t)((int)(C - name) + l_value + 2)))) 80 malloc((size_t)((int)(C - name) + l_value + 2))))
95 return (-1); 81 return (-1);
96 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) 82 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
97 ; 83 ;
98 for (*C++ = '='; *C++ = *value++; ) 84 for (*C++ = '='; (*C++ = *value++); )
99 ; 85 ;
100 return (0); 86 return (0);
101} 87}
@@ -105,15 +91,12 @@ setenv(name, value, rewrite)
105 * Delete environmental variable "name". 91 * Delete environmental variable "name".
106 */ 92 */
107void 93void
108unsetenv(name) 94unsetenv(const char *name)
109 const char *name;
110{ 95{
111 extern char **environ; 96 char **P;
112 register char **P;
113 int offset; 97 int offset;
114 char *__findenv();
115 98
116 while (__findenv(name, &offset)) /* if set multiple times */ 99 while (__findenv(name, &offset)) /* if set multiple times */
117 for (P = &environ[offset];; ++P) 100 for (P = &environ[offset];; ++P)
118 if (!(*P = *(P + 1))) 101 if (!(*P = *(P + 1)))
119 break; 102 break;
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..979334203e 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,62 @@
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.12 2008/06/13 23:50:49 jmc 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: June 13 2008 $
40.Dt STRTOD 3 35.Dt STRTOD 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtod 38.Nm strtod ,
39.Nm strtof
44.Nd convert 40.Nd convert
45.Tn ASCII 41.Tn ASCII
46string to double 42string to double or float
47.Sh SYNOPSIS 43.Sh SYNOPSIS
44.Fd #include <math.h>
48.Fd #include <stdlib.h> 45.Fd #include <stdlib.h>
49.Ft double 46.Ft double
50.Fn strtod "const char *nptr" "char **endptr" 47.Fn strtod "const char *nptr" "char **endptr"
48.Pp
49.Ft float
50.Fn strtof "const char *nptr" "char **endptr"
51.Sh DESCRIPTION 51.Sh DESCRIPTION
52The 52The
53.Fn strtod 53.Fn strtod
54function converts the initial portion of the string 54function converts the initial portion of the string pointed to by
55pointed to by 55.Fa nptr
56to
57.Li double
58representation.
59The
60.Fn strtof
61function converts the initial portion of the string pointed to by
56.Fa nptr 62.Fa nptr
57to 63to
58.Em double 64.Li float
59representation. 65representation.
60.Pp 66.Pp
61The expected form of the string is an optional plus (``+'') or minus 67The expected form of the string is an optional plus
62sign (``-'') followed by a sequence of digits optionally containing 68.Pq Ql +
69or minus sign
70.Pq Ql -
71followed by a sequence of digits optionally containing
63a decimal-point character, optionally followed by an exponent. 72a decimal-point character, optionally followed by an exponent.
64An exponent consists of an ``E'' or ``e'', followed by an optional plus 73An exponent consists of an
65or minus sign, followed by a sequence of digits. 74.Sq E
75or
76.Sq e ,
77followed by an optional plus or minus sign, followed by a sequence of digits.
66.Pp 78.Pp
67Leading white-space characters in the string (as defined by the 79Leading whitespace characters in the string (as defined by the
68.Xr isspace 3 80.Xr isspace 3
69function) are skipped. 81function) are skipped.
70.Sh RETURN VALUES 82.Sh RETURN VALUES
71The 83The
72.Fn strtod 84.Fn strtod
73function returns the converted value, if any. 85and
86.Fn strtof
87functions return the converted value, if any.
74.Pp 88.Pp
75If 89If
76.Fa endptr 90.Fa endptr
@@ -88,18 +102,18 @@ is stored in the location referenced by
88If the correct value would cause overflow, plus or minus 102If the correct value would cause overflow, plus or minus
89.Dv HUGE_VAL 103.Dv HUGE_VAL
90is returned (according to the sign of the value), and 104is returned (according to the sign of the value), and
91.Dv ERANGE 105.Er ERANGE
92is stored in 106is stored in
93.Va errno . 107.Va errno .
94If the correct value would cause underflow, zero is 108If the correct value would cause underflow, zero is returned and
95returned and 109.Er ERANGE
96.Dv ERANGE 110is stored in
97is stored in
98.Va errno . 111.Va errno .
99.Sh ERRORS 112.Sh ERRORS
100.Bl -tag -width Er 113.Bl -tag -width Er
101.It Bq Er ERANGE 114.It Bq Er ERANGE
102Overflow or underflow occurred. 115Overflow or underflow occurred.
116.El
103.Sh SEE ALSO 117.Sh SEE ALSO
104.Xr atof 3 , 118.Xr atof 3 ,
105.Xr atoi 3 , 119.Xr atoi 3 ,
@@ -109,6 +123,7 @@ Overflow or underflow occurred.
109.Sh STANDARDS 123.Sh STANDARDS
110The 124The
111.Fn strtod 125.Fn strtod
112function 126and
113conforms to 127.Fn strtof
128functions conform to
114.St -ansiC . 129.St -ansiC .
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index b13fa128f5..4dc3d65a26 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtod.c,v 1.30 2006/10/30 18:30:52 deraadt Exp $ */
1/**************************************************************** 2/****************************************************************
2 * 3 *
3 * The author of this software is David M. Gay. 4 * The author of this software is David M. Gay.
@@ -79,7 +80,6 @@
79 * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision 80 * #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 * integer arithmetic. Whether this speeds things up or slows things
81 * down depends on the machine and the number being converted. 82 * 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 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, 84 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. 85 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
@@ -89,13 +89,14 @@
89 * directly -- and assumed always to succeed. 89 * directly -- and assumed always to succeed.
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#include <sys/types.h>
93static 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__) || \ 93#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
97 defined(__mips__) || defined(__ns32k__) || defined(__alpha__) 94 defined(__mips__) || defined(__mips64__) || defined(__ns32k__) || \
98#include <machine/endian.h> 95 defined(__alpha__) || defined(__powerpc__) || defined(__m88k__) || \
96 defined(__hppa__) || defined(__amd64__) || defined(__sh__) || \
97 defined(__sparc64__) || \
98 (defined(__arm__) && defined(__VFP_FP__))
99
99#if BYTE_ORDER == BIG_ENDIAN 100#if BYTE_ORDER == BIG_ENDIAN
100#define IEEE_BIG_ENDIAN 101#define IEEE_BIG_ENDIAN
101#else 102#else
@@ -103,7 +104,16 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
103#endif 104#endif
104#endif 105#endif
105 106
106#ifdef vax 107#if defined(__arm__) && !defined(__VFP_FP__)
108/*
109 * Although the CPU is little endian the FP has different
110 * byte and word endianness. The byte order is still little endian
111 * but the word order is big endian.
112 */
113#define IEEE_BIG_ENDIAN
114#endif
115
116#ifdef __vax__
107#define VAX 117#define VAX
108#endif 118#endif
109 119
@@ -115,26 +125,22 @@ static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
115#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} 125#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
116#endif 126#endif
117 127
128#include "thread_private.h"
129
130_THREAD_PRIVATE_KEY(dtoa);
131_THREAD_PRIVATE_KEY(pow5mult);
132
118#ifdef __cplusplus 133#ifdef __cplusplus
119#include "malloc.h" 134#include "malloc.h"
120#include "memory.h" 135#include "memory.h"
121#else 136#else
122#ifndef KR_headers
123#include "stdlib.h" 137#include "stdlib.h"
124#include "string.h" 138#include "string.h"
125#include "locale.h" 139#include "locale.h"
126#else
127#include "malloc.h"
128#include "memory.h"
129#endif
130#endif 140#endif
131 141
132#ifdef MALLOC 142#ifdef MALLOC
133#ifdef KR_headers
134extern char *MALLOC();
135#else
136extern void *MALLOC(size_t); 143extern void *MALLOC(size_t);
137#endif
138#else 144#else
139#define MALLOC malloc 145#define MALLOC malloc
140#endif 146#endif
@@ -143,7 +149,6 @@ extern void *MALLOC(size_t);
143#include "errno.h" 149#include "errno.h"
144 150
145#ifdef Bad_float_h 151#ifdef Bad_float_h
146#undef __STDC__
147#ifdef IEEE_BIG_ENDIAN 152#ifdef IEEE_BIG_ENDIAN
148#define IEEE_ARITHMETIC 153#define IEEE_ARITHMETIC
149#endif 154#endif
@@ -193,12 +198,8 @@ extern "C" {
193#endif 198#endif
194 199
195#ifndef CONST 200#ifndef CONST
196#ifdef KR_headers
197#define CONST /* blank */
198#else
199#define CONST const 201#define CONST const
200#endif 202#endif
201#endif
202 203
203#ifdef Unsigned_Shifts 204#ifdef Unsigned_Shifts
204#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; 205#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
@@ -208,23 +209,27 @@ extern "C" {
208 209
209#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ 210#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
210 defined(IBM) != 1 211 defined(IBM) != 1
211Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or 212#error Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
212IBM should be defined.
213#endif 213#endif
214 214
215typedef union {
216 double d;
217 ULong ul[2];
218} _double;
219#define value(x) ((x).d)
215#ifdef IEEE_LITTLE_ENDIAN 220#ifdef IEEE_LITTLE_ENDIAN
216#define word0(x) ((ULong *)&x)[1] 221#define word0(x) ((x).ul[1])
217#define word1(x) ((ULong *)&x)[0] 222#define word1(x) ((x).ul[0])
218#else 223#else
219#define word0(x) ((ULong *)&x)[0] 224#define word0(x) ((x).ul[0])
220#define word1(x) ((ULong *)&x)[1] 225#define word1(x) ((x).ul[1])
221#endif 226#endif
222 227
223/* The following definition of Storeinc is appropriate for MIPS processors. 228/* The following definition of Storeinc is appropriate for MIPS processors.
224 * An alternative that might be better on some machines is 229 * An alternative that might be better on some machines is
225 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 230 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
226 */ 231 */
227#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) 232#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
228#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 233#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
229((unsigned short *)a)[0] = (unsigned short)c, a++) 234((unsigned short *)a)[0] = (unsigned short)c, a++)
230#else 235#else
@@ -326,11 +331,7 @@ IBM should be defined.
326#ifdef RND_PRODQUOT 331#ifdef RND_PRODQUOT
327#define rounded_product(a,b) a = rnd_prod(a, b) 332#define rounded_product(a,b) a = rnd_prod(a, b)
328#define rounded_quotient(a,b) a = rnd_quot(a, b) 333#define rounded_quotient(a,b) a = rnd_quot(a, b)
329#ifdef KR_headers
330extern double rnd_prod(), rnd_quot();
331#else
332extern double rnd_prod(double, double), rnd_quot(double, double); 334extern double rnd_prod(double, double), rnd_quot(double, double);
333#endif
334#else 335#else
335#define rounded_product(a,b) a *= b 336#define rounded_product(a,b) a *= b
336#define rounded_quotient(a,b) a /= b 337#define rounded_quotient(a,b) a /= b
@@ -369,54 +370,94 @@ Bigint {
369 370
370 static Bigint *freelist[Kmax+1]; 371 static Bigint *freelist[Kmax+1];
371 372
373#define PRIVATE_MEM 2304
374#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
375 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
376
372 static Bigint * 377 static Bigint *
373Balloc 378Balloc(int k)
374#ifdef KR_headers
375 (k) int k;
376#else
377 (int k)
378#endif
379{ 379{
380 int x; 380 int x;
381 unsigned int len;
381 Bigint *rv; 382 Bigint *rv;
382 383
383 if (rv = freelist[k]) { 384 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
385 if ((rv = freelist[k])) {
384 freelist[k] = rv->next; 386 freelist[k] = rv->next;
385 } 387 }
386 else { 388 else {
387 x = 1 << k; 389 x = 1 << k;
388 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); 390 len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1)
391 /sizeof(double);
392 if (pmem_next - private_mem + len <= PRIVATE_mem) {
393 rv = (Bigint *)pmem_next;
394 pmem_next += len;
395 }
396 else
397 rv = (Bigint *)MALLOC(len *sizeof(double));
389 rv->k = k; 398 rv->k = k;
390 rv->maxwds = x; 399 rv->maxwds = x;
391 } 400 }
401 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
392 rv->sign = rv->wds = 0; 402 rv->sign = rv->wds = 0;
393 return rv; 403 return rv;
394 } 404 }
395 405
396 static void 406 static void
397Bfree 407Bfree(Bigint *v)
398#ifdef KR_headers
399 (v) Bigint *v;
400#else
401 (Bigint *v)
402#endif
403{ 408{
404 if (v) { 409 if (v) {
410 _THREAD_PRIVATE_MUTEX_LOCK(dtoa);
405 v->next = freelist[v->k]; 411 v->next = freelist[v->k];
406 freelist[v->k] = v; 412 freelist[v->k] = v;
413 _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa);
407 } 414 }
408 } 415 }
409 416
410#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ 417#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
411y->wds*sizeof(Long) + 2*sizeof(int)) 418y->wds*sizeof(Long) + 2*sizeof(int))
412 419
420/* return value is only used as a simple string, so mis-aligned parts
421 * inside the Bigint are not at risk on strict align architectures
422 */
423 static char *
424rv_alloc(int i)
425{
426 int j, k, *r;
427
428 j = sizeof(ULong);
429 for(k = 0;
430 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
431 j <<= 1)
432 k++;
433 r = (int*)Balloc(k);
434 *r = k;
435 return (char *)(r+1);
436 }
437
438 static char *
439nrv_alloc(char *s, char **rve, int n)
440{
441 char *rv, *t;
442
443 t = rv = rv_alloc(n);
444 while((*t = *s++) !=0)
445 t++;
446 if (rve)
447 *rve = t;
448 return rv;
449 }
450
451 void
452__freedtoa(char *s)
453{
454 Bigint *b = (Bigint *)((int *)s - 1);
455 b->maxwds = 1 << (b->k = *(int*)b);
456 Bfree(b);
457 }
458
413 static Bigint * 459 static Bigint *
414multadd 460multadd(Bigint *b, int m, int a) /* multiply by m and add a */
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{ 461{
421 int i, wds; 462 int i, wds;
422 ULong *x, y; 463 ULong *x, y;
@@ -456,12 +497,7 @@ multadd
456 } 497 }
457 498
458 static Bigint * 499 static Bigint *
459s2b 500s2b(CONST char *s, int nd0, int nd, ULong y9)
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{ 501{
466 Bigint *b; 502 Bigint *b;
467 int i, k; 503 int i, k;
@@ -494,14 +530,9 @@ s2b
494 } 530 }
495 531
496 static int 532 static int
497hi0bits 533hi0bits(ULong x)
498#ifdef KR_headers
499 (x) register ULong x;
500#else
501 (register ULong x)
502#endif
503{ 534{
504 register int k = 0; 535 int k = 0;
505 536
506 if (!(x & 0xffff0000)) { 537 if (!(x & 0xffff0000)) {
507 k = 16; 538 k = 16;
@@ -528,15 +559,10 @@ hi0bits
528 } 559 }
529 560
530 static int 561 static int
531lo0bits 562lo0bits(ULong *y)
532#ifdef KR_headers
533 (y) ULong *y;
534#else
535 (ULong *y)
536#endif
537{ 563{
538 register int k; 564 int k;
539 register ULong x = *y; 565 ULong x = *y;
540 566
541 if (x & 7) { 567 if (x & 7) {
542 if (x & 1) 568 if (x & 1)
@@ -568,7 +594,7 @@ lo0bits
568 if (!(x & 1)) { 594 if (!(x & 1)) {
569 k++; 595 k++;
570 x >>= 1; 596 x >>= 1;
571 if (!x & 1) 597 if (!(x & 1))
572 return 32; 598 return 32;
573 } 599 }
574 *y = x; 600 *y = x;
@@ -576,12 +602,7 @@ lo0bits
576 } 602 }
577 603
578 static Bigint * 604 static Bigint *
579i2b 605i2b(int i)
580#ifdef KR_headers
581 (i) int i;
582#else
583 (int i)
584#endif
585{ 606{
586 Bigint *b; 607 Bigint *b;
587 608
@@ -592,12 +613,7 @@ i2b
592 } 613 }
593 614
594 static Bigint * 615 static Bigint *
595mult 616mult(Bigint *a, Bigint *b)
596#ifdef KR_headers
597 (a, b) Bigint *a, *b;
598#else
599 (Bigint *a, Bigint *b)
600#endif
601{ 617{
602 Bigint *c; 618 Bigint *c;
603 int k, wa, wb, wc; 619 int k, wa, wb, wc;
@@ -628,7 +644,7 @@ mult
628 xc0 = c->x; 644 xc0 = c->x;
629#ifdef Pack_32 645#ifdef Pack_32
630 for(; xb < xbe; xb++, xc0++) { 646 for(; xb < xbe; xb++, xc0++) {
631 if (y = *xb & 0xffff) { 647 if ((y = *xb & 0xffff)) {
632 x = xa; 648 x = xa;
633 xc = xc0; 649 xc = xc0;
634 carry = 0; 650 carry = 0;
@@ -642,7 +658,7 @@ mult
642 while(x < xae); 658 while(x < xae);
643 *xc = carry; 659 *xc = carry;
644 } 660 }
645 if (y = *xb >> 16) { 661 if ((y = *xb >> 16)) {
646 x = xa; 662 x = xa;
647 xc = xc0; 663 xc = xc0;
648 carry = 0; 664 carry = 0;
@@ -682,26 +698,23 @@ mult
682 static Bigint *p5s; 698 static Bigint *p5s;
683 699
684 static Bigint * 700 static Bigint *
685pow5mult 701pow5mult(Bigint *b, int k)
686#ifdef KR_headers
687 (b, k) Bigint *b; int k;
688#else
689 (Bigint *b, int k)
690#endif
691{ 702{
692 Bigint *b1, *p5, *p51; 703 Bigint *b1, *p5, *p51;
693 int i; 704 int i;
694 static int p05[3] = { 5, 25, 125 }; 705 static int p05[3] = { 5, 25, 125 };
695 706
696 if (i = k & 3) 707 if ((i = k & 3))
697 b = multadd(b, p05[i-1], 0); 708 b = multadd(b, p05[i-1], 0);
698 709
699 if (!(k >>= 2)) 710 if (!(k >>= 2))
700 return b; 711 return b;
701 if (!(p5 = p5s)) { 712 if (!(p5 = p5s)) {
702 /* first time */ 713 /* first time */
714 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
703 p5 = p5s = i2b(625); 715 p5 = p5s = i2b(625);
704 p5->next = 0; 716 p5->next = 0;
717 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
705 } 718 }
706 for(;;) { 719 for(;;) {
707 if (k & 1) { 720 if (k & 1) {
@@ -712,8 +725,12 @@ pow5mult
712 if (!(k >>= 1)) 725 if (!(k >>= 1))
713 break; 726 break;
714 if (!(p51 = p5->next)) { 727 if (!(p51 = p5->next)) {
715 p51 = p5->next = mult(p5,p5); 728 _THREAD_PRIVATE_MUTEX_LOCK(pow5mult);
716 p51->next = 0; 729 if (!(p51 = p5->next)) {
730 p51 = p5->next = mult(p5,p5);
731 p51->next = 0;
732 }
733 _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult);
717 } 734 }
718 p5 = p51; 735 p5 = p51;
719 } 736 }
@@ -721,12 +738,7 @@ pow5mult
721 } 738 }
722 739
723 static Bigint * 740 static Bigint *
724lshift 741lshift(Bigint *b, int k)
725#ifdef KR_headers
726 (b, k) Bigint *b; int k;
727#else
728 (Bigint *b, int k)
729#endif
730{ 742{
731 int i, k1, n, n1; 743 int i, k1, n, n1;
732 Bigint *b1; 744 Bigint *b1;
@@ -756,7 +768,7 @@ lshift
756 z = *x++ >> k1; 768 z = *x++ >> k1;
757 } 769 }
758 while(x < xe); 770 while(x < xe);
759 if (*x1 = z) 771 if ((*x1 = z))
760 ++n1; 772 ++n1;
761 } 773 }
762#else 774#else
@@ -781,12 +793,7 @@ lshift
781 } 793 }
782 794
783 static int 795 static int
784cmp 796cmp(Bigint *a, Bigint *b)
785#ifdef KR_headers
786 (a, b) Bigint *a, *b;
787#else
788 (Bigint *a, Bigint *b)
789#endif
790{ 797{
791 ULong *xa, *xa0, *xb, *xb0; 798 ULong *xa, *xa0, *xb, *xb0;
792 int i, j; 799 int i, j;
@@ -815,12 +822,7 @@ cmp
815 } 822 }
816 823
817 static Bigint * 824 static Bigint *
818diff 825diff(Bigint *a, Bigint *b)
819#ifdef KR_headers
820 (a, b) Bigint *a, *b;
821#else
822 (Bigint *a, Bigint *b)
823#endif
824{ 826{
825 Bigint *c; 827 Bigint *c;
826 int i, wa, wb; 828 int i, wa, wb;
@@ -897,16 +899,13 @@ diff
897 } 899 }
898 900
899 static double 901 static double
900ulp 902ulp(double _x)
901#ifdef KR_headers
902 (x) double x;
903#else
904 (double x)
905#endif
906{ 903{
907 register Long L; 904 _double x;
908 double a; 905 Long L;
906 _double a;
909 907
908 value(x) = _x;
910 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 909 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
911#ifndef Sudden_Underflow 910#ifndef Sudden_Underflow
912 if (L > 0) { 911 if (L > 0) {
@@ -931,20 +930,15 @@ ulp
931 } 930 }
932 } 931 }
933#endif 932#endif
934 return a; 933 return value(a);
935 } 934 }
936 935
937 static double 936 static double
938b2d 937b2d(Bigint *a, int *e)
939#ifdef KR_headers
940 (a, e) Bigint *a; int *e;
941#else
942 (Bigint *a, int *e)
943#endif
944{ 938{
945 ULong *xa, *xa0, w, y, z; 939 ULong *xa, *xa0, w, y, z;
946 int k; 940 int k;
947 double d; 941 _double d;
948#ifdef VAX 942#ifdef VAX
949 ULong d0, d1; 943 ULong d0, d1;
950#else 944#else
@@ -1001,22 +995,22 @@ b2d
1001#undef d0 995#undef d0
1002#undef d1 996#undef d1
1003#endif 997#endif
1004 return d; 998 return value(d);
1005 } 999 }
1006 1000
1007 static Bigint * 1001 static Bigint *
1008d2b 1002d2b(double _d, int *e, int *bits)
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{ 1003{
1015 Bigint *b; 1004 Bigint *b;
1016 int de, i, k; 1005 int de, i, k;
1017 ULong *x, y, z; 1006 ULong *x, y, z;
1007 _double d;
1018#ifdef VAX 1008#ifdef VAX
1019 ULong d0, d1; 1009 ULong d0, d1;
1010#endif
1011
1012 value(d) = _d;
1013#ifdef VAX
1020 d0 = word0(d) >> 16 | word0(d) << 16; 1014 d0 = word0(d) >> 16 | word0(d) << 16;
1021 d1 = word1(d) >> 16 | word1(d) << 16; 1015 d1 = word1(d) >> 16 | word1(d) << 16;
1022#else 1016#else
@@ -1134,18 +1128,13 @@ d2b
1134#undef d1 1128#undef d1
1135 1129
1136 static double 1130 static double
1137ratio 1131ratio(Bigint *a, Bigint *b)
1138#ifdef KR_headers
1139 (a, b) Bigint *a, *b;
1140#else
1141 (Bigint *a, Bigint *b)
1142#endif
1143{ 1132{
1144 double da, db; 1133 _double da, db;
1145 int k, ka, kb; 1134 int k, ka, kb;
1146 1135
1147 da = b2d(a, &ka); 1136 value(da) = b2d(a, &ka);
1148 db = b2d(b, &kb); 1137 value(db) = b2d(b, &kb);
1149#ifdef Pack_32 1138#ifdef Pack_32
1150 k = ka - kb + 32*(a->wds - b->wds); 1139 k = ka - kb + 32*(a->wds - b->wds);
1151#else 1140#else
@@ -1171,7 +1160,7 @@ ratio
1171 word0(db) += k*Exp_msk1; 1160 word0(db) += k*Exp_msk1;
1172 } 1161 }
1173#endif 1162#endif
1174 return da / db; 1163 return value(da) / value(db);
1175 } 1164 }
1176 1165
1177static CONST double 1166static CONST double
@@ -1201,32 +1190,29 @@ static CONST double tinytens[] = { 1e-16, 1e-32 };
1201#endif 1190#endif
1202 1191
1203 double 1192 double
1204strtod 1193strtod(CONST char *s00, char **se)
1205#ifdef KR_headers
1206 (s00, se) CONST char *s00; char **se;
1207#else
1208 (CONST char *s00, char **se)
1209#endif
1210{ 1194{
1211 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1195 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1212 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1196 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1213 CONST char *s, *s0, *s1; 1197 CONST char *s, *s0, *s1;
1214 double aadj, aadj1, adj, rv, rv0; 1198 double aadj, aadj1, adj;
1199 /*
1200 * volatile forces mem update for FPUs where reg size != sizeof double,
1201 * which should trigger ERANGE in the case of underflow.
1202 */
1203 volatile _double rv;
1204 _double rv0;
1215 Long L; 1205 Long L;
1216 ULong y, z; 1206 ULong y, z;
1217 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1207 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1218 1208
1219#ifndef KR_headers
1220 CONST char decimal_point = localeconv()->decimal_point[0]; 1209 CONST char decimal_point = localeconv()->decimal_point[0];
1221#else
1222 CONST char decimal_point = '.';
1223#endif
1224 1210
1225 sign = nz0 = nz = 0; 1211 sign = nz0 = nz = 0;
1226 rv = 0.; 1212 value(rv) = 0.;
1227 1213
1228 1214
1229 for(s = s00; isspace(*s); s++) 1215 for(s = s00; isspace((unsigned char) *s); s++)
1230 ; 1216 ;
1231 1217
1232 if (*s == '-') { 1218 if (*s == '-') {
@@ -1340,9 +1326,9 @@ strtod
1340 if (!nd0) 1326 if (!nd0)
1341 nd0 = nd; 1327 nd0 = nd;
1342 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1328 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
1343 rv = y; 1329 value(rv) = y;
1344 if (k > 9) 1330 if (k > 9)
1345 rv = tens[k - 9] * rv + z; 1331 value(rv) = tens[k - 9] * value(rv) + z;
1346 bd0 = 0; 1332 bd0 = 0;
1347 if (nd <= DBL_DIG 1333 if (nd <= DBL_DIG
1348#ifndef RND_PRODQUOT 1334#ifndef RND_PRODQUOT
@@ -1356,7 +1342,8 @@ strtod
1356#ifdef VAX 1342#ifdef VAX
1357 goto vax_ovfl_check; 1343 goto vax_ovfl_check;
1358#else 1344#else
1359 /* rv = */ rounded_product(rv, tens[e]); 1345 /* value(rv) = */ rounded_product(value(rv),
1346 tens[e]);
1360 goto ret; 1347 goto ret;
1361#endif 1348#endif
1362 } 1349 }
@@ -1366,27 +1353,30 @@ strtod
1366 * this for larger i values. 1353 * this for larger i values.
1367 */ 1354 */
1368 e -= i; 1355 e -= i;
1369 rv *= tens[i]; 1356 value(rv) *= tens[i];
1370#ifdef VAX 1357#ifdef VAX
1371 /* VAX exponent range is so narrow we must 1358 /* VAX exponent range is so narrow we must
1372 * worry about overflow here... 1359 * worry about overflow here...
1373 */ 1360 */
1374 vax_ovfl_check: 1361 vax_ovfl_check:
1375 word0(rv) -= P*Exp_msk1; 1362 word0(rv) -= P*Exp_msk1;
1376 /* rv = */ rounded_product(rv, tens[e]); 1363 /* value(rv) = */ rounded_product(value(rv),
1364 tens[e]);
1377 if ((word0(rv) & Exp_mask) 1365 if ((word0(rv) & Exp_mask)
1378 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1366 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1379 goto ovfl; 1367 goto ovfl;
1380 word0(rv) += P*Exp_msk1; 1368 word0(rv) += P*Exp_msk1;
1381#else 1369#else
1382 /* rv = */ rounded_product(rv, tens[e]); 1370 /* value(rv) = */ rounded_product(value(rv),
1371 tens[e]);
1383#endif 1372#endif
1384 goto ret; 1373 goto ret;
1385 } 1374 }
1386 } 1375 }
1387#ifndef Inaccurate_Divide 1376#ifndef Inaccurate_Divide
1388 else if (e >= -Ten_pmax) { 1377 else if (e >= -Ten_pmax) {
1389 /* rv = */ rounded_quotient(rv, tens[-e]); 1378 /* value(rv) = */ rounded_quotient(value(rv),
1379 tens[-e]);
1390 goto ret; 1380 goto ret;
1391 } 1381 }
1392#endif 1382#endif
@@ -1397,13 +1387,13 @@ strtod
1397 1387
1398 if (e1 > 0) { 1388 if (e1 > 0) {
1399 if (i = e1 & 15) 1389 if (i = e1 & 15)
1400 rv *= tens[i]; 1390 value(rv) *= tens[i];
1401 if (e1 &= ~15) { 1391 if (e1 &= ~15) {
1402 if (e1 > DBL_MAX_10_EXP) { 1392 if (e1 > DBL_MAX_10_EXP) {
1403 ovfl: 1393 ovfl:
1404 errno = ERANGE; 1394 errno = ERANGE;
1405#ifdef __STDC__ 1395#ifndef Bad_float_h
1406 rv = HUGE_VAL; 1396 value(rv) = HUGE_VAL;
1407#else 1397#else
1408 /* Can't trust HUGE_VAL */ 1398 /* Can't trust HUGE_VAL */
1409#ifdef IEEE_Arith 1399#ifdef IEEE_Arith
@@ -1421,10 +1411,10 @@ strtod
1421 if (e1 >>= 4) { 1411 if (e1 >>= 4) {
1422 for(j = 0; e1 > 1; j++, e1 >>= 1) 1412 for(j = 0; e1 > 1; j++, e1 >>= 1)
1423 if (e1 & 1) 1413 if (e1 & 1)
1424 rv *= bigtens[j]; 1414 value(rv) *= bigtens[j];
1425 /* The last multiplication could overflow. */ 1415 /* The last multiplication could overflow. */
1426 word0(rv) -= P*Exp_msk1; 1416 word0(rv) -= P*Exp_msk1;
1427 rv *= bigtens[j]; 1417 value(rv) *= bigtens[j];
1428 if ((z = word0(rv) & Exp_mask) 1418 if ((z = word0(rv) & Exp_mask)
1429 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1419 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1430 goto ovfl; 1420 goto ovfl;
@@ -1443,23 +1433,23 @@ strtod
1443 else if (e1 < 0) { 1433 else if (e1 < 0) {
1444 e1 = -e1; 1434 e1 = -e1;
1445 if (i = e1 & 15) 1435 if (i = e1 & 15)
1446 rv /= tens[i]; 1436 value(rv) /= tens[i];
1447 if (e1 &= ~15) { 1437 if (e1 &= ~15) {
1448 e1 >>= 4; 1438 e1 >>= 4;
1449 if (e1 >= 1 << n_bigtens) 1439 if (e1 >= 1 << n_bigtens)
1450 goto undfl; 1440 goto undfl;
1451 for(j = 0; e1 > 1; j++, e1 >>= 1) 1441 for(j = 0; e1 > 1; j++, e1 >>= 1)
1452 if (e1 & 1) 1442 if (e1 & 1)
1453 rv *= tinytens[j]; 1443 value(rv) *= tinytens[j];
1454 /* The last multiplication could underflow. */ 1444 /* The last multiplication could underflow. */
1455 rv0 = rv; 1445 value(rv0) = value(rv);
1456 rv *= tinytens[j]; 1446 value(rv) *= tinytens[j];
1457 if (!rv) { 1447 if (!value(rv)) {
1458 rv = 2.*rv0; 1448 value(rv) = 2.*value(rv0);
1459 rv *= tinytens[j]; 1449 value(rv) *= tinytens[j];
1460 if (!rv) { 1450 if (!value(rv)) {
1461 undfl: 1451 undfl:
1462 rv = 0.; 1452 value(rv) = 0.;
1463 errno = ERANGE; 1453 errno = ERANGE;
1464 if (bd0) 1454 if (bd0)
1465 goto retfree; 1455 goto retfree;
@@ -1483,7 +1473,7 @@ strtod
1483 for(;;) { 1473 for(;;) {
1484 bd = Balloc(bd0->k); 1474 bd = Balloc(bd0->k);
1485 Bcopy(bd, bd0); 1475 Bcopy(bd, bd0);
1486 bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ 1476 bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
1487 bs = i2b(1); 1477 bs = i2b(1);
1488 1478
1489 if (e >= 0) { 1479 if (e >= 0) {
@@ -1595,12 +1585,12 @@ strtod
1595 break; 1585 break;
1596#endif 1586#endif
1597 if (dsign) 1587 if (dsign)
1598 rv += ulp(rv); 1588 value(rv) += ulp(value(rv));
1599#ifndef ROUND_BIASED 1589#ifndef ROUND_BIASED
1600 else { 1590 else {
1601 rv -= ulp(rv); 1591 value(rv) -= ulp(value(rv));
1602#ifndef Sudden_Underflow 1592#ifndef Sudden_Underflow
1603 if (!rv) 1593 if (!value(rv))
1604 goto undfl; 1594 goto undfl;
1605#endif 1595#endif
1606 } 1596 }
@@ -1651,10 +1641,10 @@ strtod
1651 /* Check for overflow */ 1641 /* Check for overflow */
1652 1642
1653 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 1643 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
1654 rv0 = rv; 1644 value(rv0) = value(rv);
1655 word0(rv) -= P*Exp_msk1; 1645 word0(rv) -= P*Exp_msk1;
1656 adj = aadj1 * ulp(rv); 1646 adj = aadj1 * ulp(value(rv));
1657 rv += adj; 1647 value(rv) += adj;
1658 if ((word0(rv) & Exp_mask) >= 1648 if ((word0(rv) & Exp_mask) >=
1659 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 1649 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
1660 if (word0(rv0) == Big0 && word1(rv0) == Big1) 1650 if (word0(rv0) == Big0 && word1(rv0) == Big1)
@@ -1669,10 +1659,10 @@ strtod
1669 else { 1659 else {
1670#ifdef Sudden_Underflow 1660#ifdef Sudden_Underflow
1671 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 1661 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
1672 rv0 = rv; 1662 value(rv0) = value(rv);
1673 word0(rv) += P*Exp_msk1; 1663 word0(rv) += P*Exp_msk1;
1674 adj = aadj1 * ulp(rv); 1664 adj = aadj1 * ulp(value(rv));
1675 rv += adj; 1665 value(rv) += adj;
1676#ifdef IBM 1666#ifdef IBM
1677 if ((word0(rv) & Exp_mask) < P*Exp_msk1) 1667 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
1678#else 1668#else
@@ -1690,8 +1680,8 @@ strtod
1690 word0(rv) -= P*Exp_msk1; 1680 word0(rv) -= P*Exp_msk1;
1691 } 1681 }
1692 else { 1682 else {
1693 adj = aadj1 * ulp(rv); 1683 adj = aadj1 * ulp(value(rv));
1694 rv += adj; 1684 value(rv) += adj;
1695 } 1685 }
1696#else 1686#else
1697 /* Compute adj so that the IEEE rounding rules will 1687 /* Compute adj so that the IEEE rounding rules will
@@ -1706,8 +1696,8 @@ strtod
1706 if (!dsign) 1696 if (!dsign)
1707 aadj1 = -aadj1; 1697 aadj1 = -aadj1;
1708 } 1698 }
1709 adj = aadj1 * ulp(rv); 1699 adj = aadj1 * ulp(value(rv));
1710 rv += adj; 1700 value(rv) += adj;
1711#endif 1701#endif
1712 } 1702 }
1713 z = word0(rv) & Exp_mask; 1703 z = word0(rv) & Exp_mask;
@@ -1738,16 +1728,11 @@ strtod
1738 ret: 1728 ret:
1739 if (se) 1729 if (se)
1740 *se = (char *)s; 1730 *se = (char *)s;
1741 return sign ? -rv : rv; 1731 return sign ? -value(rv) : value(rv);
1742 } 1732 }
1743 1733
1744 static int 1734 static int
1745quorem 1735quorem(Bigint *b, Bigint *S)
1746#ifdef KR_headers
1747 (b, S) Bigint *b, *S;
1748#else
1749 (Bigint *b, Bigint *S)
1750#endif
1751{ 1736{
1752 int n; 1737 int n;
1753 Long borrow, y; 1738 Long borrow, y;
@@ -1882,13 +1867,7 @@ quorem
1882 */ 1867 */
1883 1868
1884 char * 1869 char *
1885__dtoa 1870__dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve)
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{ 1871{
1893 /* Arguments ndigits, decpt, sign are similar to those 1872 /* Arguments ndigits, decpt, sign are similar to those
1894 of ecvt and fcvt; trailing zeros are suppressed from 1873 of ecvt and fcvt; trailing zeros are suppressed from
@@ -1933,17 +1912,11 @@ __dtoa
1933 ULong x; 1912 ULong x;
1934#endif 1913#endif
1935 Bigint *b, *b1, *delta, *mlo, *mhi, *S; 1914 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
1936 double d2, ds, eps; 1915 double ds;
1937 char *s, *s0; 1916 char *s, *s0;
1938 static Bigint *result; 1917 _double d, d2, eps;
1939 static int result_k;
1940 1918
1941 if (result) { 1919 value(d) = _d;
1942 result->k = result_k;
1943 result->maxwds = 1 << result_k;
1944 Bfree(result);
1945 result = 0;
1946 }
1947 1920
1948 if (word0(d) & Sign_bit) { 1921 if (word0(d) & Sign_bit) {
1949 /* set sign for everything, including 0's and NaNs */ 1922 /* set sign for everything, including 0's and NaNs */
@@ -1962,43 +1935,33 @@ __dtoa
1962 { 1935 {
1963 /* Infinity or NaN */ 1936 /* Infinity or NaN */
1964 *decpt = 9999; 1937 *decpt = 9999;
1965 s =
1966#ifdef IEEE_Arith 1938#ifdef IEEE_Arith
1967 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : 1939 if (!word1(d) && !(word0(d) & 0xfffff))
1940 return nrv_alloc("Infinity", rve, 8);
1968#endif 1941#endif
1969 "NaN"; 1942 return nrv_alloc("NaN", rve, 3);
1970 if (rve)
1971 *rve =
1972#ifdef IEEE_Arith
1973 s[3] ? s + 8 :
1974#endif
1975 s + 3;
1976 return s;
1977 } 1943 }
1978#endif 1944#endif
1979#ifdef IBM 1945#ifdef IBM
1980 d += 0; /* normalize */ 1946 value(d) += 0; /* normalize */
1981#endif 1947#endif
1982 if (!d) { 1948 if (!value(d)) {
1983 *decpt = 1; 1949 *decpt = 1;
1984 s = "0"; 1950 return nrv_alloc("0", rve, 1);
1985 if (rve)
1986 *rve = s + 1;
1987 return s;
1988 } 1951 }
1989 1952
1990 b = d2b(d, &be, &bbits); 1953 b = d2b(value(d), &be, &bbits);
1991#ifdef Sudden_Underflow 1954#ifdef Sudden_Underflow
1992 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 1955 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
1993#else 1956#else
1994 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 1957 if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
1995#endif 1958#endif
1996 d2 = d; 1959 value(d2) = value(d);
1997 word0(d2) &= Frac_mask1; 1960 word0(d2) &= Frac_mask1;
1998 word0(d2) |= Exp_11; 1961 word0(d2) |= Exp_11;
1999#ifdef IBM 1962#ifdef IBM
2000 if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 1963 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2001 d2 /= 1 << j; 1964 value(d2) /= 1 << j;
2002#endif 1965#endif
2003 1966
2004 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 1967 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
@@ -2037,19 +2000,20 @@ __dtoa
2037 i = bbits + be + (Bias + (P-1) - 1); 2000 i = bbits + be + (Bias + (P-1) - 1);
2038 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2001 x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
2039 : word1(d) << 32 - i; 2002 : word1(d) << 32 - i;
2040 d2 = x; 2003 value(d2) = x;
2041 word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2004 word0(d2) -= 31*Exp_msk1; /* adjust exponent */
2042 i -= (Bias + (P-1) - 1) + 1; 2005 i -= (Bias + (P-1) - 1) + 1;
2043 denorm = 1; 2006 denorm = 1;
2044 } 2007 }
2045#endif 2008#endif
2046 ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2009 ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2010 i*0.301029995663981;
2047 k = (int)ds; 2011 k = (int)ds;
2048 if (ds < 0. && ds != k) 2012 if (ds < 0. && ds != k)
2049 k--; /* want k = floor(ds) */ 2013 k--; /* want k = floor(ds) */
2050 k_check = 1; 2014 k_check = 1;
2051 if (k >= 0 && k <= Ten_pmax) { 2015 if (k >= 0 && k <= Ten_pmax) {
2052 if (d < tens[k]) 2016 if (value(d) < tens[k])
2053 k--; 2017 k--;
2054 k_check = 0; 2018 k_check = 0;
2055 } 2019 }
@@ -2105,18 +2069,14 @@ __dtoa
2105 if (i <= 0) 2069 if (i <= 0)
2106 i = 1; 2070 i = 1;
2107 } 2071 }
2108 j = sizeof(ULong); 2072 s = s0 = rv_alloc(i);
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 2073
2114 if (ilim >= 0 && ilim <= Quick_max && try_quick) { 2074 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2115 2075
2116 /* Try to get by with floating-point arithmetic. */ 2076 /* Try to get by with floating-point arithmetic. */
2117 2077
2118 i = 0; 2078 i = 0;
2119 d2 = d; 2079 value(d2) = value(d);
2120 k0 = k; 2080 k0 = k;
2121 ilim0 = ilim; 2081 ilim0 = ilim;
2122 ieps = 2; /* conservative */ 2082 ieps = 2; /* conservative */
@@ -2126,7 +2086,7 @@ __dtoa
2126 if (j & Bletch) { 2086 if (j & Bletch) {
2127 /* prevent overflows */ 2087 /* prevent overflows */
2128 j &= Bletch - 1; 2088 j &= Bletch - 1;
2129 d /= bigtens[n_bigtens-1]; 2089 value(d) /= bigtens[n_bigtens-1];
2130 ieps++; 2090 ieps++;
2131 } 2091 }
2132 for(; j; j >>= 1, i++) 2092 for(; j; j >>= 1, i++)
@@ -2134,32 +2094,32 @@ __dtoa
2134 ieps++; 2094 ieps++;
2135 ds *= bigtens[i]; 2095 ds *= bigtens[i];
2136 } 2096 }
2137 d /= ds; 2097 value(d) /= ds;
2138 } 2098 }
2139 else if (j1 = -k) { 2099 else if (j1 = -k) {
2140 d *= tens[j1 & 0xf]; 2100 value(d) *= tens[j1 & 0xf];
2141 for(j = j1 >> 4; j; j >>= 1, i++) 2101 for(j = j1 >> 4; j; j >>= 1, i++)
2142 if (j & 1) { 2102 if (j & 1) {
2143 ieps++; 2103 ieps++;
2144 d *= bigtens[i]; 2104 value(d) *= bigtens[i];
2145 } 2105 }
2146 } 2106 }
2147 if (k_check && d < 1. && ilim > 0) { 2107 if (k_check && value(d) < 1. && ilim > 0) {
2148 if (ilim1 <= 0) 2108 if (ilim1 <= 0)
2149 goto fast_failed; 2109 goto fast_failed;
2150 ilim = ilim1; 2110 ilim = ilim1;
2151 k--; 2111 k--;
2152 d *= 10.; 2112 value(d) *= 10.;
2153 ieps++; 2113 ieps++;
2154 } 2114 }
2155 eps = ieps*d + 7.; 2115 value(eps) = ieps*value(d) + 7.;
2156 word0(eps) -= (P-1)*Exp_msk1; 2116 word0(eps) -= (P-1)*Exp_msk1;
2157 if (ilim == 0) { 2117 if (ilim == 0) {
2158 S = mhi = 0; 2118 S = mhi = 0;
2159 d -= 5.; 2119 value(d) -= 5.;
2160 if (d > eps) 2120 if (value(d) > value(eps))
2161 goto one_digit; 2121 goto one_digit;
2162 if (d < -eps) 2122 if (value(d) < -value(eps))
2163 goto no_digits; 2123 goto no_digits;
2164 goto fast_failed; 2124 goto fast_failed;
2165 } 2125 }
@@ -2168,33 +2128,33 @@ __dtoa
2168 /* Use Steele & White method of only 2128 /* Use Steele & White method of only
2169 * generating digits needed. 2129 * generating digits needed.
2170 */ 2130 */
2171 eps = 0.5/tens[ilim-1] - eps; 2131 value(eps) = 0.5/tens[ilim-1] - value(eps);
2172 for(i = 0;;) { 2132 for(i = 0;;) {
2173 L = d; 2133 L = value(d);
2174 d -= L; 2134 value(d) -= L;
2175 *s++ = '0' + (int)L; 2135 *s++ = '0' + (int)L;
2176 if (d < eps) 2136 if (value(d) < value(eps))
2177 goto ret1; 2137 goto ret1;
2178 if (1. - d < eps) 2138 if (1. - value(d) < value(eps))
2179 goto bump_up; 2139 goto bump_up;
2180 if (++i >= ilim) 2140 if (++i >= ilim)
2181 break; 2141 break;
2182 eps *= 10.; 2142 value(eps) *= 10.;
2183 d *= 10.; 2143 value(d) *= 10.;
2184 } 2144 }
2185 } 2145 }
2186 else { 2146 else {
2187#endif 2147#endif
2188 /* Generate ilim digits, then fix them up. */ 2148 /* Generate ilim digits, then fix them up. */
2189 eps *= tens[ilim-1]; 2149 value(eps) *= tens[ilim-1];
2190 for(i = 1;; i++, d *= 10.) { 2150 for(i = 1;; i++, value(d) *= 10.) {
2191 L = d; 2151 L = value(d);
2192 d -= L; 2152 value(d) -= L;
2193 *s++ = '0' + (int)L; 2153 *s++ = '0' + (int)L;
2194 if (i == ilim) { 2154 if (i == ilim) {
2195 if (d > 0.5 + eps) 2155 if (value(d) > 0.5 + value(eps))
2196 goto bump_up; 2156 goto bump_up;
2197 else if (d < 0.5 - eps) { 2157 else if (value(d) < 0.5 - value(eps)) {
2198 while(*--s == '0'); 2158 while(*--s == '0');
2199 s++; 2159 s++;
2200 goto ret1; 2160 goto ret1;
@@ -2207,7 +2167,7 @@ __dtoa
2207#endif 2167#endif
2208 fast_failed: 2168 fast_failed:
2209 s = s0; 2169 s = s0;
2210 d = d2; 2170 value(d) = value(d2);
2211 k = k0; 2171 k = k0;
2212 ilim = ilim0; 2172 ilim = ilim0;
2213 } 2173 }
@@ -2219,24 +2179,24 @@ __dtoa
2219 ds = tens[k]; 2179 ds = tens[k];
2220 if (ndigits < 0 && ilim <= 0) { 2180 if (ndigits < 0 && ilim <= 0) {
2221 S = mhi = 0; 2181 S = mhi = 0;
2222 if (ilim < 0 || d <= 5*ds) 2182 if (ilim < 0 || value(d) <= 5*ds)
2223 goto no_digits; 2183 goto no_digits;
2224 goto one_digit; 2184 goto one_digit;
2225 } 2185 }
2226 for(i = 1;; i++) { 2186 for(i = 1;; i++) {
2227 L = d / ds; 2187 L = value(d) / ds;
2228 d -= L*ds; 2188 value(d) -= L*ds;
2229#ifdef Check_FLT_ROUNDS 2189#ifdef Check_FLT_ROUNDS
2230 /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2190 /* If FLT_ROUNDS == 2, L will usually be high by 1 */
2231 if (d < 0) { 2191 if (value(d) < 0) {
2232 L--; 2192 L--;
2233 d += ds; 2193 value(d) += ds;
2234 } 2194 }
2235#endif 2195#endif
2236 *s++ = '0' + (int)L; 2196 *s++ = '0' + (int)L;
2237 if (i == ilim) { 2197 if (i == ilim) {
2238 d += d; 2198 value(d) += value(d);
2239 if (d > ds || d == ds && L & 1) { 2199 if (value(d) > ds || value(d) == ds && L & 1) {
2240 bump_up: 2200 bump_up:
2241 while(*--s == '9') 2201 while(*--s == '9')
2242 if (s == s0) { 2202 if (s == s0) {
@@ -2248,7 +2208,7 @@ __dtoa
2248 } 2208 }
2249 break; 2209 break;
2250 } 2210 }
2251 if (!(d *= 10.)) 2211 if (!(value(d) *= 10.))
2252 break; 2212 break;
2253 } 2213 }
2254 goto ret1; 2214 goto ret1;
diff --git a/src/lib/libc/stdlib/strtof.c b/src/lib/libc/stdlib/strtof.c
new file mode 100644
index 0000000000..8c8db47ad8
--- /dev/null
+++ b/src/lib/libc/stdlib/strtof.c
@@ -0,0 +1,39 @@
1/* $OpenBSD: strtof.c,v 1.1 2008/06/13 21:04:24 landry Exp $ */
2
3/*
4 * Copyright (c) 2008 Landry Breuil
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#include <math.h>
24
25float
26strtof(const char *s00, char **se)
27{
28 double d;
29
30 d = strtod(s00, se);
31 if (d > FLT_MAX) {
32 errno = ERANGE;
33 return (FLT_MAX);
34 } else if (d < -FLT_MAX) {
35 errno = ERANGE;
36 return (-FLT_MAX);
37 }
38 return ((float) d);
39}
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 */
42intmax_t
43strtoimax(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..84d9a0c427 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.19 2007/11/13 18:30:04 tobias 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: November 13 2007 $
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>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
45.Fd #include <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
49.Ft long long
50.Fn strtoll "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <inttypes.h>
53.Ft intmax_t
54.Fn strtoimax "const char *nptr" "char **endptr" "int base"
55.Pp
51.Fd #include <sys/types.h> 56.Fd #include <sys/types.h>
52.Fd #include <stdlib.h>
53.Fd #include <limits.h> 57.Fd #include <limits.h>
58.Fd #include <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
57The 62The
58.Fn strtol 63.Fn strtol
59function 64function converts the string in
60converts the string in
61.Fa nptr 65.Fa nptr
62to a 66to a
63.Em long 67.Li long
64value. 68value.
65The 69The
66.Fn strtoq 70.Fn strtoll
67function 71function converts the string in
68converts the string in
69.Fa nptr 72.Fa nptr
70to a 73to a
71.Em quad_t 74.Li long long
72value. 75value.
76The
77.Fn strtoimax
78function converts the string in
79.Fa nptr
80to an
81.Li intmax_t
82value.
83The
84.Fn strtoq
85function is a deprecated equivalent of
86.Fn strtoll
87and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 88The conversion is done according to the given
74.Fa base , 89.Fa base ,
75which must be between 2 and 36 inclusive, 90which must be a number between 2 and 36 inclusive or the special value 0.
76or be the special value 0.
77.Pp 91.Pp
78The string may begin with an arbitrary amount of white space 92The 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 )
81followed by a single optional 95followed by a single optional
@@ -85,25 +99,25 @@ or
85sign. 99sign.
86If 100If
87.Fa base 101.Fa base
88is zero or 16, 102is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 103.Ql 0x
91prefix, 104prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 105.Fa base
94is taken as 10 (decimal) unless the next character is 106is taken as 10 (decimal) unless the next character is
95.Ql 0 , 107.Ql 0 ,
96in which case it is taken as 8 (octal). 108in which case it is taken as 8 (octal).
97.Pp 109.Pp
98The remainder of the string is converted to a 110The remainder of the string is converted to a
99.Em long 111.Li long ,
112.Li long long ,
113or
114.Li intmax_t ,
100value in the obvious manner, 115value in the obvious manner,
101stopping at the first character which is not a valid digit 116stopping at the first character which is not a valid digit
102in the given base. 117in the given base.
103(In bases above 10, the letter 118(In bases above 10, the letter
104.Ql A 119.Ql A
105in either upper or lower case 120in either upper or lower case represents 10,
106represents 10,
107.Ql B 121.Ql B
108represents 11, and so forth, with 122represents 11, and so forth, with
109.Ql Z 123.Ql Z
@@ -111,7 +125,7 @@ representing 35.)
111.Pp 125.Pp
112If 126If
113.Fa endptr 127.Fa endptr
114is non nil, 128is non-null,
115.Fn strtol 129.Fn strtol
116stores the address of the first invalid character in 130stores the address of the first invalid character in
117.Fa *endptr . 131.Fa *endptr .
@@ -132,22 +146,93 @@ is
132on return, the entire string was valid.) 146on return, the entire string was valid.)
133.Sh RETURN VALUES 147.Sh RETURN VALUES
134The 148The
135.Fn strtol 149.Fn strtol ,
136function 150.Fn strtoll ,
137returns the result of the conversion, 151.Fn strtoimax ,
152and
153.Fn strtoq
154functions return the result of the conversion,
138unless the value would underflow or overflow. 155unless the value would underflow or overflow.
139If an underflow occurs, 156If no conversion could be performed, 0 is returned;
140.Fn strtol 157the global variable
141returns 158.Va errno
142.Dv LONG_MIN . 159is also set to
143If an overflow occurs, 160.Er EINVAL,
144.Fn strtol 161though this is not portable across all platforms.
145returns 162If overflow or underflow occurs,
146.Dv LONG_MAX .
147In both cases,
148.Va errno 163.Va errno
149is set to 164is set to
150.Er ERANGE . 165.Er ERANGE
166and the function return value is as follows:
167.Bl -column -offset indent "strtoimax" "overflow" "underflow"
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
175Ensuring that a string is a valid number (i.e., in range and containing no
176trailing characters) requires clearing
177.Va errno
178beforehand explicitly since
179.Va errno
180is not changed on a successful call to
181.Fn strtol ,
182and the return value of
183.Fn strtol
184cannot be used unambiguously to signal an error:
185.Bd -literal -offset indent
186char *ep;
187long lval;
188
189\&...
190
191errno = 0;
192lval = strtol(buf, &ep, 10);
193if (buf[0] == '\e0' || *ep != '\e0')
194 goto not_a_number;
195if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
196 goto out_of_range;
197.Ed
198.Pp
199This example will accept
200.Dq 12
201but not
202.Dq 12foo
203or
204.Dq 12\en .
205If trailing whitespace is acceptable, further checks must be done on
206.Va *ep ;
207alternately, use
208.Xr sscanf 3 .
209.Pp
210If
211.Fn strtol
212is being used instead of
213.Xr atoi 3 ,
214error checking is further complicated because the desired return value is an
215.Li int
216rather than a
217.Li long ;
218however, on some architectures integers and long integers are the same size.
219Thus the following is necessary:
220.Bd -literal -offset indent
221char *ep;
222int ival;
223long lval;
224
225\&...
226
227errno = 0;
228lval = strtol(buf, &ep, 10);
229if (buf[0] == '\e0' || *ep != '\e0')
230 goto not_a_number;
231if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
232 (lval > INT_MAX || lval < INT_MIN))
233 goto out_of_range;
234ival = 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
163The 251The
164.Fn strtol 252.Fn strtol ,
165function 253.Fn strtoll ,
166conforms to 254and
167.St -ansiC . 255.Fn strtoimax
256functions conform to
257.St -ansiC-99 .
258The
259.Fn strtoq
260function is a
261.Bx
262extension and is provided for backwards compatibility with legacy programs.
168.Sh BUGS 263.Sh BUGS
169Ignores the current locale. 264Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..5a244766db 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.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,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";*/
36static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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,30 @@ 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 */
51long 43long
52strtol(nptr, endptr, base) 44strtol(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;
62 50
63 /* 51 /*
64 * Skip white space and pick up leading +/- sign if any. 52 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 53 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 54 * assume decimal; if base is already 16, allow 0x.
67 */ 55 */
56 s = nptr;
68 do { 57 do {
69 c = *s++; 58 c = (unsigned char) *s++;
70 } while (isspace(c)); 59 } while (isspace(c));
71 if (c == '-') { 60 if (c == '-') {
72 neg = 1; 61 neg = 1;
73 c = *s++; 62 c = *s++;
74 } else if (c == '+') 63 } else {
75 c = *s++; 64 neg = 0;
65 if (c == '+')
66 c = *s++;
67 }
76 if ((base == 0 || base == 16) && 68 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 69 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 70 c = s[1];
@@ -99,10 +91,17 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 91 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 92 * overflow.
101 */ 93 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 94 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 95 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 96 cutoff /= base;
105 for (acc = 0, any = 0;; c = *s++) { 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++) {
106 if (isdigit(c)) 105 if (isdigit(c))
107 c -= '0'; 106 c -= '0';
108 else if (isalpha(c)) 107 else if (isalpha(c))
@@ -111,19 +110,30 @@ strtol(nptr, endptr, base)
111 break; 110 break;
112 if (c >= base) 111 if (c >= base)
113 break; 112 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 113 if (any < 0)
115 any = -1; 114 continue;
116 else { 115 if (neg) {
117 any = 1; 116 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 117 any = -1;
119 acc += c; 118 acc = LONG_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 = LONG_MAX;
129 errno = ERANGE;
130 } else {
131 any = 1;
132 acc *= base;
133 acc += c;
134 }
120 } 135 }
121 } 136 }
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) 137 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 138 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 139 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoll.c
index fc559e9d7f..37379252e3 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.6 2005/11/10 10:00:17 espie 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)
35static 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 */
51quad_t 44long long
52strtoq(nptr, endptr, base) 45strtoll(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,42 @@ 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#ifdef __weak_alias
145__weak_alias(strtoq, strtoll);
146#else
147quad_t
148strtoq(const char *nptr, char **endptr, int base)
149{
150
151 return ((quad_t)strtoll(nptr, endptr, base));
152}
153#endif
diff --git a/src/lib/libc/stdlib/strtonum.3 b/src/lib/libc/stdlib/strtonum.3
new file mode 100644
index 0000000000..58b4112ac3
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.3
@@ -0,0 +1,152 @@
1.\" $OpenBSD: strtonum.3,v 1.14 2007/05/31 19:19:31 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: May 31 2007 $
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.Fd #include <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
33The
34.Fn strtonum
35function converts the string in
36.Fa nptr
37to a
38.Li long long
39value.
40The
41.Fn strtonum
42function was designed to facilitate safe, robust programming
43and overcome the shortcomings of the
44.Xr atoi 3
45and
46.Xr strtol 3
47family of interfaces.
48.Pp
49The string may begin with an arbitrary amount of whitespace
50(as determined by
51.Xr isspace 3 )
52followed by a single optional
53.Ql +
54or
55.Ql -
56sign.
57.Pp
58The remainder of the string is converted to a
59.Li long long
60value according to base 10.
61.Pp
62The value obtained is then checked against the provided
63.Fa minval
64and
65.Fa maxval
66bounds.
67If
68.Fa errstr
69is non-null,
70.Fn strtonum
71stores an error string in
72.Fa *errstr
73indicating the failure.
74.Sh RETURN VALUES
75The
76.Fn strtonum
77function returns the result of the conversion,
78unless the value would exceed the provided bounds or is invalid.
79On error, 0 is returned,
80.Va errno
81is set, and
82.Fa errstr
83will point to an error message.
84.Fa *errstr
85will be set to
86.Dv NULL
87on success;
88this fact can be used to differentiate
89a successful return of 0 from an error.
90.Sh EXAMPLES
91Using
92.Fn strtonum
93correctly is meant to be simpler than the alternative functions.
94.Bd -literal -offset indent
95int iterations;
96const char *errstr;
97
98iterations = strtonum(optarg, 1, 64, &errstr);
99if (errstr)
100 errx(1, "number of iterations is %s: %s", errstr, optarg);
101.Ed
102.Pp
103The above example will guarantee that the value of iterations is between
1041 and 64 (inclusive).
105.Sh ERRORS
106.Bl -tag -width Er
107.It Bq Er ERANGE
108The given string was out of range.
109.It Bq Er EINVAL
110The given string did not consist solely of digit characters.
111.It Bq Er EINVAL
112.Ar minval
113was larger than
114.Ar maxval .
115.El
116.Pp
117If an error occurs,
118.Fa errstr
119will be set to one of the following strings:
120.Pp
121.Bl -tag -width "too largeXX" -compact
122.It too large
123The result was larger than the provided maximum value.
124.It too small
125The result was smaller than the provided minimum value.
126.It invalid
127The 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
140is an
141.Ox
142extension.
143The existing alternatives, such as
144.Xr atoi 3
145and
146.Xr strtol 3 ,
147are either impossible or difficult to use safely.
148.Sh HISTORY
149The
150.Fn strtonum
151function 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..e426388ed0
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.c
@@ -0,0 +1,65 @@
1/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert 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
28long long
29strtonum(const char *numstr, long long minval, long long maxval,
30 const char **errstrp)
31{
32 long long ll = 0;
33 char *ep;
34 int error = 0;
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..a7c6bbfa18 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,73 @@
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.19 2007/11/13 18:30:04 tobias 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: November 13 2007 $
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>
47.Fd #include <limits.h> 44.Fd #include <limits.h>
45.Fd #include <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.Pp
49.Ft unsigned long long
50.Fn strtoull "const char *nptr" "char **endptr" "int base"
51.Pp
52.Fd #include <inttypes.h>
53.Ft uintmax_t
54.Fn strtoumax "const char *nptr" "char **endptr" "int base"
55.Pp
51.Fd #include <sys/types.h> 56.Fd #include <sys/types.h>
52.Fd #include <stdlib.h>
53.Fd #include <limits.h> 57.Fd #include <limits.h>
58.Fd #include <stdlib.h>
54.Ft u_quad_t 59.Ft u_quad_t
55.Fn strtouq "const char *nptr" "char **endptr" "int base" 60.Fn strtouq "const char *nptr" "char **endptr" "int base"
56.Sh DESCRIPTION 61.Sh DESCRIPTION
57The 62The
58.Fn strtoul 63.Fn strtoul
59function 64function converts the string in
60converts the string in
61.Fa nptr 65.Fa nptr
62to an 66to an
63.Em unsigned long 67.Li unsigned long
64value. 68value.
65The 69The
66.Fn strtouq 70.Fn strtoull
67function 71function converts the string in
68converts the string in 72.Fa nptr
73to an
74.Li unsigned long long
75value.
76The
77.Fn strtoumax
78function converts the string in
69.Fa nptr 79.Fa nptr
70to a 80to a
71.Em u_quad_t 81.Li umaxint_t
72value. 82value.
83The
84.Fn strtouq
85function is a deprecated equivalent of
86.Fn strtoull
87and is provided for backwards compatibility with legacy programs.
73The conversion is done according to the given 88The conversion is done according to the given
74.Fa base , 89.Fa base ,
75which must be between 2 and 36 inclusive, 90which must be a number between 2 and 36 inclusive
76or be the special value 0. 91or the special value 0.
92If the string in
93.Fa nptr
94represents a negative number, it will be converted to its unsigned equivalent.
95This behavior is consistent with what happens when a signed integer type is
96cast to its unsigned counterpart.
77.Pp 97.Pp
78The string may begin with an arbitrary amount of white space 98The string may begin with an arbitrary amount of whitespace
79(as determined by 99(as determined by
80.Xr isspace 3 ) 100.Xr isspace 3 )
81followed by a single optional 101followed by a single optional
@@ -85,26 +105,22 @@ or
85sign. 105sign.
86If 106If
87.Fa base 107.Fa base
88is zero or 16, 108is zero or 16, the string may then include a
89the string may then include a
90.Ql 0x 109.Ql 0x
91prefix, 110prefix, and the number will be read in base 16; otherwise, a zero
92and the number will be read in base 16; otherwise, a zero
93.Fa base 111.Fa base
94is taken as 10 (decimal) unless the next character is 112is taken as 10 (decimal) unless the next character is
95.Ql 0 , 113.Ql 0 ,
96in which case it is taken as 8 (octal). 114in which case it is taken as 8 (octal).
97.Pp 115.Pp
98The remainder of the string is converted to an 116The remainder of the string is converted to an
99.Em unsigned long 117.Li unsigned long
100value in the obvious manner, 118value in the obvious manner, stopping at the end of the string
101stopping at the end of the string
102or at the first character that does not produce a valid digit 119or at the first character that does not produce a valid digit
103in the given base. 120in the given base.
104(In bases above 10, the letter 121(In bases above 10, the letter
105.Ql A 122.Ql A
106in either upper or lower case 123in either upper or lower case represents 10,
107represents 10,
108.Ql B 124.Ql B
109represents 11, and so forth, with 125represents 11, and so forth, with
110.Ql Z 126.Ql Z
@@ -112,7 +128,7 @@ representing 35.)
112.Pp 128.Pp
113If 129If
114.Fa endptr 130.Fa endptr
115is non nil, 131is non-null,
116.Fn strtoul 132.Fn strtoul
117stores the address of the first invalid character in 133stores the address of the first invalid character in
118.Fa *endptr . 134.Fa *endptr .
@@ -133,32 +149,100 @@ is
133on return, the entire string was valid.) 149on return, the entire string was valid.)
134.Sh RETURN VALUES 150.Sh RETURN VALUES
135The 151The
136.Fn strtoul 152.Fn strtoul ,
137function 153.Fn strtoull ,
138returns either the result of the conversion 154.Fn strtoumax
139or, if there was a leading minus sign, 155and
156.Fn strtouq
157functions return either the result of the conversion or,
158if there was a leading minus sign,
140the negation of the result of the conversion, 159the negation of the result of the conversion,
141unless the original (non-negated) value would overflow; 160unless the original (non-negated) value would overflow.
142in the latter case, 161If overflow occurs,
143.Fn strtoul 162.Fn strtoul
144returns 163returns
145.Dv ULONG_MAX 164.Dv ULONG_MAX ,
146and sets the global variable 165.Fn strtoull
166returns
167.Dv ULLONG_MAX ,
168.Fn strtoumax
169returns
170.Dv UINTMAX_MAX ,
171.Fn strtouq
172returns
173.Dv ULLONG_MAX
174and the global variable
147.Va errno 175.Va errno
148to 176is set to
149.Er ERANGE . 177.Er ERANGE .
178If no conversion could be performed, 0 is returned;
179the global variable
180.Va errno
181is also set to
182.Er EINVAL,
183though this is not portable across all platforms.
184.Pp
185There is no way to determine if
186.Fn strtoul
187has processed a negative number (and returned an unsigned value) short of
188examining the string in
189.Fa nptr
190directly.
191.Sh EXAMPLES
192Ensuring that a string is a valid number (i.e., in range and containing no
193trailing characters) requires clearing
194.Va errno
195beforehand explicitly since
196.Va errno
197is not changed on a successful call to
198.Fn strtoul ,
199and the return value of
200.Fn strtoul
201cannot be used unambiguously to signal an error:
202.Bd -literal -offset indent
203char *ep;
204unsigned long ulval;
205
206\&...
207
208errno = 0;
209ulval = strtoul(buf, &ep, 10);
210if (buf[0] == '\e0' || *ep != '\e0')
211 goto not_a_number;
212if (errno == ERANGE && ulval == ULONG_MAX)
213 goto out_of_range;
214.Ed
215.Pp
216This example will accept
217.Dq 12
218but not
219.Dq 12foo
220or
221.Dq 12\en .
222If trailing whitespace is acceptable, further checks must be done on
223.Va *ep ;
224alternately, use
225.Xr sscanf 3 .
150.Sh ERRORS 226.Sh ERRORS
151.Bl -tag -width Er 227.Bl -tag -width Er
152.It Bq Er ERANGE 228.It Bq Er ERANGE
153The given string was out of range; the value converted has been clamped. 229The given string was out of range; the value converted has been clamped.
154.El 230.El
155.Sh SEE ALSO 231.Sh SEE ALSO
232.Xr sscanf 3 ,
156.Xr strtol 3 233.Xr strtol 3
157.Sh STANDARDS 234.Sh STANDARDS
158The 235The
159.Fn strtoul 236.Fn strtoul ,
160function 237.Fn strtoull ,
161conforms to 238and
162.St -ansiC . 239.Fn strtoumax
240functions conform to
241.St -ansiC-99 .
242The
243.Fn strtouq
244function is a
245.Bx
246extension and is provided for backwards compatibility with legacy programs.
163.Sh BUGS 247.Sh BUGS
164Ignores the current locale. 248Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..d7dddab778 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.7 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.
@@ -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";*/
36static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 */
50unsigned long 42unsigned long
51strtoul(nptr, endptr, base) 43strtoul(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..37859776f9 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.5 2005/08/08 08:05:37 espie 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)
35static 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 */
51u_quad_t 44unsigned long long
52strtouq(nptr, endptr, base) 45strtoull(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,32 @@ 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#ifdef __weak_alias
107__weak_alias(strtouq, strtoull);
108#else
109u_quad_t
110strtouq(const char *nptr, char **endptr, int base)
111{
112
113 return ((u_quad_t)strtoull(nptr, endptr, base));
114}
115#endif
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 */
42uintmax_t
43strtoumax(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..a49e595bc0 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,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: @(#)system.3 6.5 (Berkeley) 6/29/91 32.\" $OpenBSD: system.3,v 1.11 2008/04/04 19:30:41 kurt 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: April 4 2008 $
40.Dt SYSTEM 3 35.Dt SYSTEM 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn system 46.Fn system
52function 47function hands the argument
53hands the argument
54.Fa string 48.Fa string
55to the command interpreter 49to the command interpreter
56.Xr sh 1 . 50.Xr sh 1 .
@@ -64,36 +58,47 @@ and blocking
64.Pp 58.Pp
65If 59If
66.Fa string 60.Fa string
67is a 61is
68.Dv NULL 62.Dv NULL ,
69pointer,
70.Fn system 63.Fn system
71will return non-zero. 64will return non-zero.
72Otherwise, 65Otherwise,
73.Fn system 66.Fn system
74returns the termination status of the shell in the format specified by 67returns the termination status of the shell in the format specified by
75.Xr waitpid 3 . 68.Xr waitpid 2 .
76.Sh RETURN VALUES 69.Pp
70Note that fork handlers established using
71.Xr pthread_atfork 3
72are not called when a multithreaded program calls
73.Fn system .
74.Sh RETURN VALUES
77If a child process cannot be created, or the termination status of 75If a child process cannot be created, or the termination status of
78the shell cannot be obtained, 76the shell cannot be obtained,
79.Fn system 77.Fn system
80returns -1 and sets 78returns \-1 and sets
81.Va errno 79.Va errno
82to indicate the error. 80to indicate the error.
83If execution of the shell fails, 81If execution of the shell fails,
84.Fn system 82.Fn system
85returns the termination status for a program that terminates with a call of 83returns 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
93The 91The
94.Fn system 92.Fn system
95function 93function conforms to
96conforms to 94.St -ansiC
97.St -ansiC
98and 95and
99.St -1003.2-92 . 96.St -p1003.2-92 .
97.Sh CAVEATS
98Never supply the
99.Fn system
100function with a command containing any part of an unsanitized user-supplied
101string.
102Shell meta-characters present will be honored by the
103.Xr sh 1
104command 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";*/
36static char *rcsid = "$Id: system.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 $"
46extern char **environ; 38extern char **environ;
47 39
48int 40int
49system(command) 41system(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..ff6bcd742d
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/* $OpenBSD: tfind.c,v 1.5 2005/03/30 18:51:49 pat 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, lint doesn't grok it.
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
16typedef struct node_t
17{
18 char *key;
19 struct node_t *llink, *rlink;
20} node;
21
22/* find a node, or return 0 */
23void *
24tfind(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..0a52822620
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,127 @@
1.\" $OpenBSD: tsearch.3,v 1.16 2007/05/31 19:19:32 jmc 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: May 31 2007 $
18.Dt TSEARCH 3
19.Os
20.Sh NAME
21.Nm tsearch ,
22.Nm tfind ,
23.Nm tdelete ,
24.Nm twalk
25.Nd manipulate binary search trees
26.Sh SYNOPSIS
27.Fd #include <search.h>
28.Ft void *
29.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
30.Ft void *
31.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)"
32.Ft void *
33.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
34.Ft void
35.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)"
36.Sh DESCRIPTION
37The
38.Fn tdelete ,
39.Fn tfind ,
40.Fn tsearch ,
41and
42.Fn twalk
43functions manage binary search trees based on algorithms T and D
44from Knuth (6.2.2).
45The comparison function passed in by
46the user has the same style of return values as
47.Xr strcmp 3 .
48.Pp
49.Fn tfind
50searches for the datum matched by the argument
51.Fa key
52in the binary tree rooted at
53.Fa rootp ,
54returning a pointer to the datum if it is found and
55.Dv NULL
56if it is not.
57.Pp
58.Fn tsearch
59is identical to
60.Fn tfind
61except that if no match is found,
62.Fa key
63is inserted into the tree and a pointer to it is returned.
64If
65.Fa rootp
66points to a null value a new binary search tree is created.
67.Pp
68.Fn tdelete
69deletes a node from the specified binary search tree and returns
70a pointer to the parent of the node to be deleted.
71It takes the same arguments as
72.Fn tfind
73and
74.Fn tsearch .
75If the node to be deleted is the root of the binary search tree,
76.Fa rootp
77will be adjusted and a pointer to the new root will be returned.
78.Pp
79.Fn twalk
80walks the binary search tree rooted in
81.Fa root
82and calls the function
83.Fa action
84on each node.
85.Fa action
86is called with three arguments: a pointer to the current node,
87a value from the enum
88.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
89specifying the traversal type, and a node level (where level
90zero is the root of the tree).
91.Sh RETURN VALUES
92The
93.Fn tsearch
94function returns
95.Dv NULL
96if allocation of a new node fails (usually
97due to a lack of free memory).
98.Pp
99.Fn tfind ,
100.Fn tsearch ,
101and
102.Fn tdelete
103return
104.Dv NULL
105if
106.Fa rootp
107is
108.Dv NULL
109or the datum cannot be found.
110.Pp
111The
112.Fn twalk
113function returns no value.
114.Sh SEE ALSO
115.Xr bsearch 3 ,
116.Xr lsearch 3
117.Sh STANDARDS
118These functions conform to
119.St -p1003.1-2004 .
120.Sh CAVEATS
121The
122.St -p1003.1-2004
123standard does not specify what value should be returned when deleting the
124root node.
125Since implementations vary, the user of the
126.Fn tdelete
127function should not rely 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..667c57731b
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,121 @@
1/* $OpenBSD: tsearch.c,v 1.6 2006/04/04 11:21:50 moritz 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, lint doesn't grok it.
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
18typedef struct node_t {
19 char *key;
20 struct node_t *left, *right;
21} node;
22
23/* find or insert datum into search tree */
24void *
25tsearch(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 */
53void *
54tdelete(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;
60 node *q;
61 node *r;
62 int cmp;
63
64 if (rootp == (struct node_t **)0 || (p = *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 if (p == *rootp)
90 p = q;
91 free((struct node_t *) *rootp); /* D4: Free node */
92 *rootp = q; /* link parent to new node */
93 return(p);
94}
95
96/* Walk the nodes of a tree */
97static void
98trecurse(node *root, void (*action)(const void *, VISIT, int), int level)
99{
100 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
101 (*action)(root, leaf, level);
102 else {
103 (*action)(root, preorder, level);
104 if (root->left != (struct node_t *)0)
105 trecurse(root->left, action, level + 1);
106 (*action)(root, postorder, level);
107 if (root->right != (struct node_t *)0)
108 trecurse(root->right, action, level + 1);
109 (*action)(root, endorder, level);
110 }
111}
112
113/* Walk the nodes of a tree */
114void
115twalk(const void *vroot, void (*action)(const void *, VISIT, int))
116{
117 node *root = (node *)vroot;
118
119 if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
120 trecurse(root, action, 0);
121}
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
index 2b7ce63a63..124469cd3a 100644
--- a/src/lib/libc/string/Makefile.inc
+++ b/src/lib/libc/string/Makefile.inc
@@ -1,36 +1,44 @@
1# from: @(#)Makefile.inc 5.6 (Berkeley) 3/5/91 1# $OpenBSD: Makefile.inc,v 1.20 2007/10/25 22:41:02 miod Exp $
2# $Id: Makefile.inc,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
3 2
4# string sources 3# string sources
5.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string ${LIBCSRCDIR}/string
6 5
7SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \ 6SRCS+= bm.c memccpy.c memrchr.c strcasecmp.c strcasestr.c strcoll.c strdup.c \
8 strftime.c strmode.c strsignal.c strtok.c strxfrm.c \ 7 strerror.c strerror_r.c strlcat.c strmode.c strsignal.c strtok.c \
9 __strerror.c __strsignal.c 8 strxfrm.c \
9 wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
10 wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \
11 wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \
12 wmemmove.c wmemset.c
10 13
11# machine-dependent net sources 14# machine-dependent net sources
12# m-d Makefile.inc must include sources for: 15# m-d Makefile.inc must include sources for:
13# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset() 16# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset()
14# rindex() strcat() strcmp() strcpy() strcspn() strlen() 17# rindex() strcat() strcmp() strcpy() strcspn() strlen() strlcpy()
15# strncat() strncmp() strncpy() strpbrk() strsep() 18# strncat() strncmp() strncpy() strpbrk() strsep()
16# strspn() strstr() swav() 19# strspn() strstr() swav()
17# m-d Makefile.inc may include sources for: 20# m-d Makefile.inc may include sources for:
18# memcpy() memmove() strchr() strrchr() 21# memcpy() memmove() strchr() strrchr()
19 22
20.include "${.CURDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc" 23.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string/Makefile.inc"
21 24
22# if no machine specific memmove(3), build one out of bcopy(3). 25# if no machine specific memmove(3), build one out of bcopy(3).
23.if empty(SRCS:Mmemmove.S) 26.if empty(SRCS:Mmemmove.S)
24OBJS+= memmove.o 27OBJS+= memmove.o
25memmove.o: bcopy.c 28memmove.o: bcopy.c
26 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} 29 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
27 @${LD} -x -r ${.TARGET} 30 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
28 @mv a.out ${.TARGET} 31 @mv ${.TARGET}.tmp ${.TARGET}
32
33memmove.go: bcopy.c
34 ${CC} -g -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
35 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
36 @mv ${.TARGET}.tmp ${.TARGET}
29 37
30memmove.po: bcopy.c 38memmove.po: bcopy.c
31 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 39 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
32 @${LD} -X -r ${.TARGET} 40 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
33 @mv a.out ${.TARGET} 41 @mv ${.TARGET}.tmp ${.TARGET}
34 42
35memmove.so: bcopy.c 43memmove.so: bcopy.c
36 ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ 44 ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
@@ -45,13 +53,18 @@ memmove.so: bcopy.c
45OBJS+= memcpy.o 53OBJS+= memcpy.o
46memcpy.o: bcopy.c 54memcpy.o: bcopy.c
47 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} 55 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
48 @${LD} -x -r ${.TARGET} 56 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
49 @mv a.out ${.TARGET} 57 @mv ${.TARGET}.tmp ${.TARGET}
58
59memcpy.go: bcopy.c
60 ${CC} -g -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
61 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
62 @mv ${.TARGET}.tmp ${.TARGET}
50 63
51memcpy.po: bcopy.c 64memcpy.po: bcopy.c
52 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 65 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
53 @${LD} -X -r ${.TARGET} 66 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
54 @mv a.out ${.TARGET} 67 @mv ${.TARGET}.tmp ${.TARGET}
55 68
56memcpy.so: bcopy.c 69memcpy.so: bcopy.c
57 ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ 70 ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
@@ -64,13 +77,18 @@ memcpy.so: bcopy.c
64OBJS+= strchr.o 77OBJS+= strchr.o
65strchr.o: index.c 78strchr.o: index.c
66 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} 79 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
67 @${LD} -x -r ${.TARGET} 80 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
68 @mv a.out ${.TARGET} 81 @mv ${.TARGET}.tmp ${.TARGET}
82
83strchr.go: index.c
84 ${CC} -g -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
85 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
86 @mv ${.TARGET}.tmp ${.TARGET}
69 87
70strchr.po: index.c 88strchr.po: index.c
71 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 89 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
72 @${LD} -X -r ${.TARGET} 90 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
73 @mv a.out ${.TARGET} 91 @mv ${.TARGET}.tmp ${.TARGET}
74 92
75strchr.so: index.c 93strchr.so: index.c
76 ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ 94 ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
@@ -82,27 +100,79 @@ strchr.so: index.c
82OBJS+= strrchr.o 100OBJS+= strrchr.o
83strrchr.o: rindex.c 101strrchr.o: rindex.c
84 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET} 102 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
85 @${LD} -x -r ${.TARGET} 103 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
86 @mv a.out ${.TARGET} 104 @mv ${.TARGET}.tmp ${.TARGET}
105
106strrchr.go: rindex.c
107 ${CC} -g -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
108 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
109 @mv ${.TARGET}.tmp ${.TARGET}
87 110
88strrchr.po: rindex.c 111strrchr.po: rindex.c
89 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET} 112 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
90 @${LD} -X -r ${.TARGET} 113 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
91 @mv a.out ${.TARGET} 114 @mv ${.TARGET}.tmp ${.TARGET}
92 115
93strrchr.so: rindex.c 116strrchr.so: rindex.c
94 ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \ 117 ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
95 -o ${.TARGET} 118 -o ${.TARGET}
96.endif 119.endif
97 120
98MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ 121# build .ln files for memmove, memcpy, strchr and strrchr always from
99 memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ 122# bcopy, index, and rindex
100 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 strftime.3 \ 123LOBJS+= memmove.ln memcpy.ln strchr.ln strrchr.ln
124
125memmove.ln: bcopy.c
126 lint ${LINTFLAGS} -DMEMMOVE ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
127 ${LIBCSRCDIR}/string/bcopy.c
128
129memcpy.ln: bcopy.c
130 lint ${LINTFLAGS} -DMEMCOPY ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
131 ${LIBCSRCDIR}/string/bcopy.c
132
133strchr.ln: index.c
134 lint ${LINTFLAGS} -DSTRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
135 ${LIBCSRCDIR}/string/index.c
136
137strrchr.ln: rindex.c
138 lint ${LINTFLAGS} -DSTRRCHR ${CFLAGS:M-[IDU]*} -i -o ${.TARGET} \
139 ${LIBCSRCDIR}/string/rindex.c
140
141MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \
142 memcmp.3 memcpy.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \
143 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \
101 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \ 144 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
102 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 145 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3 \
146 wcstok.3 wmemchr.3
103 147
104MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3 148MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3
149MLINKS+=memchr.3 memrchr.3
150MLINKS+=strchr.3 index.3
151MLINKS+=strrchr.3 rindex.3
105MLINKS+=strcasecmp.3 strncasecmp.3 152MLINKS+=strcasecmp.3 strncasecmp.3
106MLINKS+=strcat.3 strncat.3 153MLINKS+=strcat.3 strncat.3
107MLINKS+=strcmp.3 strncmp.3 154MLINKS+=strcmp.3 strncmp.3
108MLINKS+=strcpy.3 strncpy.3 155MLINKS+=strcpy.3 strncpy.3
156MLINKS+=strlcpy.3 strlcat.3
157MLINKS+=strstr.3 strcasestr.3
158MLINKS+=strtok.3 strtok_r.3
159MLINKS+=strerror.3 strerror_r.3
160MLINKS+=wmemchr.3 wmemcmp.3
161MLINKS+=wmemchr.3 wmemcpy.3
162MLINKS+=wmemchr.3 wmemmove.3
163MLINKS+=wmemchr.3 wmemset.3
164MLINKS+=wmemchr.3 wcscat.3
165MLINKS+=wmemchr.3 wcschr.3
166MLINKS+=wmemchr.3 wcscmp.3
167MLINKS+=wmemchr.3 wcscpy.3
168MLINKS+=wmemchr.3 wcscspn.3
169MLINKS+=wmemchr.3 wcslcat.3
170MLINKS+=wmemchr.3 wcslcpy.3
171MLINKS+=wmemchr.3 wcslen.3
172MLINKS+=wmemchr.3 wcsncat.3
173MLINKS+=wmemchr.3 wcsncmp.3
174MLINKS+=wmemchr.3 wcsncpy.3
175MLINKS+=wmemchr.3 wcspbrk.3
176MLINKS+=wmemchr.3 wcsrchr.3
177MLINKS+=wmemchr.3 wcsspn.3
178MLINKS+=wmemchr.3 wcsstr.3
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
index 118c55c579..57e1a0fade 100644
--- a/src/lib/libc/string/bcmp.3
+++ b/src/lib/libc/string/bcmp.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,12 +27,11 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bcmp.3 5.4 (Berkeley) 4/19/91 30.\" $OpenBSD: bcmp.3,v 1.7 2007/05/31 19:19:32 jmc 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: May 31 2007 $
38.Dt BCMP 3 33.Dt BCMP 3
39.Os BSD 4.2 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bcmp 36.Nm bcmp
42.Nd compare byte string 37.Nd compare byte string
@@ -47,8 +42,7 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn bcmp 44.Fn bcmp
50function 45function compares byte string
51compares byte string
52.Fa b1 46.Fa b1
53against byte string 47against byte string
54.Fa b2 , 48.Fa b2 ,
@@ -68,5 +62,5 @@ The strings may overlap.
68.Sh HISTORY 62.Sh HISTORY
69A 63A
70.Fn bcmp 64.Fn bcmp
71function first appeared in 65function first appeared in
72.Bx 4.2 . 66.Bx 4.2 .
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c
index 2cc38baee3..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";*/
36static char *rcsid = "$Id: bcmp.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 */
44bcmp(b1, b2, length) 41int
45 const void *b1, *b2; 42bcmp(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..3d3c8ee958 100644
--- a/src/lib/libc/string/bcopy.3
+++ b/src/lib/libc/string/bcopy.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,15 +28,14 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)bcopy.3 5.3 (Berkeley) 4/19/91 31.\" $OpenBSD: bcopy.3,v 1.9 2007/05/31 19:19:32 jmc 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: May 31 2007 $
39.Dt BCOPY 3 34.Dt BCOPY 3
40.Os BSD 4.2 35.Os
41.Sh NAME 36.Sh NAME
42.Nm bcopy 37.Nm bcopy
43.Nd copy byte string 38.Nd copy bytes
44.Sh SYNOPSIS 39.Sh SYNOPSIS
45.Fd #include <string.h> 40.Fd #include <string.h>
46.Ft void 41.Ft void
@@ -48,14 +43,13 @@
48.Sh DESCRIPTION 43.Sh DESCRIPTION
49The 44The
50.Fn bcopy 45.Fn bcopy
51function 46function copies
52copies
53.Fa len 47.Fa len
54bytes from string 48bytes from buffer
55.Fa src 49.Fa src
56to string 50to buffer
57.Fa dst . 51.Fa dst .
58The two strings may overlap. 52The two buffers may overlap.
59If 53If
60.Fa len 54.Fa len
61is zero, no bytes are copied. 55is zero, no bytes are copied.
@@ -64,9 +58,10 @@ is zero, no bytes are copied.
64.Xr memcpy 3 , 58.Xr memcpy 3 ,
65.Xr memmove 3 , 59.Xr memmove 3 ,
66.Xr strcpy 3 , 60.Xr strcpy 3 ,
61.Xr strlcpy 3 ,
67.Xr strncpy 3 62.Xr strncpy 3
68.Sh HISTORY 63.Sh HISTORY
69A 64A
70.Fn bcopy 65.Fn bcopy
71function appeared in 66function appeared in
72.Bx 4.2 . 67.Bx 4.2 .
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c
index 92feed66ea..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";*/
39static char *rcsid = "$Id: bcopy.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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
59void * 51void *
60memcpy(dst0, src0, length) 52memcpy(void *dst0, const void *src0, size_t length)
61#else 53#else
62#ifdef MEMMOVE 54#ifdef MEMMOVE
63void * 55void *
64memmove(dst0, src0, length) 56memmove(void *dst0, const void *src0, size_t length)
65#else 57#else
66void 58void
67bcopy(src0, dst0, length) 59bcopy(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
index 2264a6a1c4..749ffc9b74 100644
--- a/src/lib/libc/string/bm.3
+++ b/src/lib/libc/string/bm.3
@@ -12,11 +12,7 @@
12.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the 13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution. 14.\" documentation and/or other materials provided with the distribution.
15.\" 3. All advertising materials mentioning features or use of this software 15.\" 3. Neither the name of the University nor the names of its contributors
16.\" must display the following acknowledgement:
17.\" This product includes software developed by the University of
18.\" California, Berkeley and its contributors.
19.\" 4. Neither the name of the University nor the names of its contributors
20.\" may be used to endorse or promote products derived from this software 16.\" may be used to endorse or promote products derived from this software
21.\" without specific prior written permission. 17.\" without specific prior written permission.
22.\" 18.\"
@@ -32,83 +28,85 @@
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE. 29.\" SUCH DAMAGE.
34.\" 30.\"
35.\" from: @(#)bm.3 8.4 (Berkeley) 6/21/94 31.\" $OpenBSD: bm.3,v 1.9 2007/05/31 19:19:32 jmc Exp $
36.\" $Id: bm.3,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
37.\" 32.\"
38.TH BM 3 33.Dd $Mdocdate: May 31 2007 $
39.SH NAME 34.Dt BM 3
40bm_comp, bm_exec, bm_free \- Boyer-Moore string search 35.Os
41.SH SYNOPSIS 36.Sh NAME
42.ft B 37.Nm bm_comp ,
43#include <sys/types.h> 38.Nm bm_exec ,
44.br 39.Nm bm_free
45#include <bm.h> 40.Nd Boyer-Moore string search
46.sp 41.Sh SYNOPSIS
47bm_pat * 42.Fd #include <sys/types.h>
48.br 43.Fd #include <bm.h>
49bm_comp(u_char *pattern, size_t patlen, u_char freq[256]); 44.Ft bm_pat *
50.sp 45.Fn bm_comp "const unsigned char *pattern" "size_t patlen" \
51u_char * 46 "const unsigned char freq[256]"
52.br 47.Ft unsigned char *
53bm_exec(bm_pat *pdesc, u_char *text, size_t len); 48.Fn bm_exec "bm_pat *pdesc" "unsigned char *text" "size_t len"
54.sp 49.Ft void
55void 50.Fn bm_free "bm_pat *pdesc"
56.br 51.Sh DESCRIPTION
57bm_free(bm_pat *pdesc);
58.SH DESCRIPTION
59These routines implement an efficient mechanism to find an 52These routines implement an efficient mechanism to find an
60occurrence of a byte string within another byte string. 53occurrence of a byte string within another byte string.
61.PP 54.Pp
62.I Bm_comp 55.Fn bm_comp
63evaluates the 56evaluates
64.I patlen 57.Fa patlen
65bytes starting at 58bytes starting at
66.IR pattern , 59.Fa pattern
67and returns a pointer to a structure describing them. 60and returns a pointer to a structure describing them.
68The bytes referenced by 61The bytes referenced by
69.I pattern 62.Fa pattern
70may be of any value. 63may be of any value.
71.PP 64.Pp
72The search takes advantage of the frequency distribution of the 65The search takes advantage of the frequency distribution of the
73bytes in the text to be searched. 66bytes in the text to be searched.
74If specified, 67If specified,
75.I freq 68.Ar freq
76should be an array of 256 values, 69should be an array of 256 values,
77with higher values indicating that the corresponding character occurs 70with higher values indicating that the corresponding character occurs
78more frequently. 71more frequently.
79(A less than optimal frequency distribution can only result in less 72(A less than optimal frequency distribution can only result in less
80than optimal performance, not incorrect results.) 73than optimal performance, not incorrect results.)
81If 74If
82.I freq 75.Ar freq
83is NULL, 76is
77.Dv NULL ,
84a system default table is used. 78a system default table is used.
85.PP 79.Pp
86.I Bm_exec 80.Fn bm_exec
87returns a pointer to the leftmost occurrence of the string given to 81returns a pointer to the leftmost occurrence of the string given to
88.I bm_comp 82.Fn bm_comp
89within 83within
90.IR text , 84.Ar text ,
91or NULL if none occurs. 85or
86.Dv NULL
87if none occurs.
92The number of bytes in 88The number of bytes in
93.I text 89.Ar text
94must be specified by 90must be specified by
95.IR len . 91.Ar len .
96.PP 92.Pp
97Space allocated for the returned description is discarded 93Space allocated for the returned description is discarded
98by calling 94by calling
99.I bm_free 95.Fn bm_free
100with the returned description as an argument. 96with the returned description as an argument.
101.PP 97.Pp
102The asymptotic speed of 98The asymptotic speed of
103.I bm_exec 99.Fn bm_exec
104is 100is
105.RI O( len / patlen ). 101.Pf O Ns Pq len / patlen .
106.PP 102.Sh SEE ALSO
107.SH "SEE ALSO" 103.Xr regexp 3 ,
108.IR regexp (3), 104.Xr strstr 3
109.IR strstr (3) 105.Rs
110.sp 106.%R "Fast String Searching"
111.IR "Fast String Searching" , 107.%A Andrew Hume
112Hume and Sunday, 108.%A Daniel Sunday
113Software Practice and Experience, 109.%J "Software Practice and Experience"
114Vol. 21, 11 (November 1991) pp. 1221-48. 110.%V Volume 21, 11 (November 1991)
111.%P 1221-48
112.Re
diff --git a/src/lib/libc/string/bm.c b/src/lib/libc/string/bm.c
index 68eac22ecc..2c4c6ca720 100644
--- a/src/lib/libc/string/bm.c
+++ b/src/lib/libc/string/bm.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: bm.c,v 1.7 2007/09/02 15:19:18 deraadt Exp $ */
1/*- 2/*-
2 * Copyright (c) 1994 3 * Copyright (c) 1994
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#ifndef lint
38/* from: static char sccsid[] = "@(#)bm.c 8.7 (Berkeley) 6/21/94"; */
39static 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> 34#include <sys/types.h>
43 35
44#include <bm.h> 36#include <bm.h>
@@ -90,14 +82,11 @@ static u_char const freq_def[256] = {
90}; 82};
91 83
92bm_pat * 84bm_pat *
93bm_comp(pb, len, freq) 85bm_comp(u_char const *pb, size_t len, u_char const *freq)
94 u_char const *pb;
95 size_t len;
96 u_char const *freq;
97{ 86{
98 register u_char const *pe, *p; 87 u_char const *pe, *p;
99 register size_t *d, r; 88 size_t *d, r;
100 register int j; 89 int j;
101 int sv_errno; 90 int sv_errno;
102 bm_pat *pat; 91 bm_pat *pat;
103 92
@@ -115,7 +104,7 @@ bm_comp(pb, len, freq)
115 goto mem; 104 goto mem;
116 memcpy(pat->pat, pb, pat->patlen); 105 memcpy(pat->pat, pb, pat->patlen);
117 /* get skip delta */ 106 /* get skip delta */
118 if ((pat->delta = malloc(256 * sizeof(*d))) == NULL) 107 if ((pat->delta = calloc(256, sizeof(*d))) == NULL)
119 goto mem; 108 goto mem;
120 for (j = 0, d = pat->delta; j < 256; j++) 109 for (j = 0, d = pat->delta; j < 256; j++)
121 d[j] = pat->patlen; 110 d[j] = pat->patlen;
@@ -147,8 +136,7 @@ mem: sv_errno = errno;
147} 136}
148 137
149void 138void
150bm_free(pat) 139bm_free(bm_pat *pat)
151 bm_pat *pat;
152{ 140{
153 if (pat->pat != NULL) 141 if (pat->pat != NULL)
154 free(pat->pat); 142 free(pat->pat);
@@ -158,14 +146,11 @@ bm_free(pat)
158} 146}
159 147
160u_char * 148u_char *
161bm_exec(pat, base, n) 149bm_exec(bm_pat *pat, u_char *base, size_t n)
162 bm_pat *pat;
163 u_char *base;
164 size_t n;
165{ 150{
166 register u_char *e, *ep, *p, *q, *s; 151 u_char *e, *ep, *p, *q, *s;
167 register size_t *d0, k, md2, n1, ro; 152 size_t *d0, k, md2, n1, ro;
168 register int rc; 153 int rc;
169 154
170 if (n == 0) 155 if (n == 0)
171 return (NULL); 156 return (NULL);
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3
index 12fcfb0cc1..cd16ab022d 100644
--- a/src/lib/libc/string/bstring.3
+++ b/src/lib/libc/string/bstring.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,22 +27,13 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bstring.3 6.8 (Berkeley) 4/19/91 30.\" $OpenBSD: bstring.3,v 1.8 2007/05/31 19:19:32 jmc Exp $
35.\" $Id: bstring.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd $Mdocdate: May 31 2007 $
38.Dt BSTRING 3 33.Dt BSTRING 3
39.Os 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bcmp , 36.Nm bstring
42.Nm bcopy ,
43.Nm bzero ,
44.Nm memccpy ,
45.Nm memchr ,
46.Nm memcmp ,
47.Nm memcpy ,
48.Nm memmove,
49.Nm memset
50.Nd byte string operations 37.Nd byte string operations
51.Sh SYNOPSIS 38.Sh SYNOPSIS
52.Fd #include <string.h> 39.Fd #include <string.h>
@@ -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
72These functions operate on variable length strings of bytes. 59These functions operate on variable length strings of bytes.
73They do not check for terminating null bytes as the routines 60They do not check for terminating NUL bytes as the routines
74listed in 61listed in
75.Xr string 3 62.Xr string 3
76do. 63do.
@@ -97,14 +84,15 @@ and
97conform to 84conform to
98.St -ansiC . 85.St -ansiC .
99.Sh HISTORY 86.Sh HISTORY
100The functions 87The
101.Fn bzero 88.Fn bzero
102and 89and
103.Fn memccpy 90.Fn memccpy
104appeared in 91functions appeared in
105.Bx 4.3 ; 92.Bx 4.3 .
106the functions 93The
107.Fn bcmp , 94.Fn bcmp
108.Fn bcopy , 95and
109appeared in 96.Fn bcopy
97functions appeared in
110.Bx 4.2 . 98.Bx 4.2 .
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3
index 4f0141e051..c5ca32f4d2 100644
--- a/src/lib/libc/string/bzero.3
+++ b/src/lib/libc/string/bzero.3
@@ -11,11 +11,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 16.\" without specific prior written permission.
21.\" 17.\"
@@ -31,12 +27,11 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
33.\" 29.\"
34.\" from: @(#)bzero.3 5.3 (Berkeley) 4/19/91 30.\" $OpenBSD: bzero.3,v 1.7 2007/05/31 19:19:32 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: May 31 2007 $
38.Dt BZERO 3 33.Dt BZERO 3
39.Os BSD 4.3 34.Os
40.Sh NAME 35.Sh NAME
41.Nm bzero 36.Nm bzero
42.Nd write zeroes to a byte string 37.Nd write zeroes to a byte string
@@ -47,8 +42,7 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn bzero 44.Fn bzero
50function 45function writes
51writes
52.Fa len 46.Fa len
53zero bytes to the string 47zero bytes to the string
54.Fa b . 48.Fa b .
@@ -63,6 +57,5 @@ does nothing.
63.Sh HISTORY 57.Sh HISTORY
64A 58A
65.Fn bzero 59.Fn bzero
66function 60function appeared in
67appeared in
68.Bx 4.3 . 61.Bx 4.3 .
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c
index 4865e396ef..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";*/
36static char *rcsid = "$Id: bzero.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 */
44void 41void
45bzero(b, length) 42bzero(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/ffs.3 b/src/lib/libc/string/ffs.3
index 6464bea2b1..27b26969e5 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,10 +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.\" from: @(#)ffs.3 5.3 (Berkeley) 4/19/91 30.\" $OpenBSD: ffs.3,v 1.5 2007/05/31 19:19:32 jmc 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: May 31 2007 $
38.Dt FFS 3 33.Dt FFS 3
39.Os 34.Os
40.Sh NAME 35.Sh NAME
@@ -47,12 +42,10 @@
47.Sh DESCRIPTION 42.Sh DESCRIPTION
48The 43The
49.Fn ffs 44.Fn ffs
50function 45function finds the first bit set in
51finds the first bit set in
52.Fa value 46.Fa value
53and returns the index of that bit. 47and returns the index of that bit.
54Bits are numbered starting from 1, starting at the right-most 48Bits are numbered starting from 1, starting at the rightmost bit.
55bit.
56A return value of 0 means that the argument was zero. 49A return value of 0 means that the argument was zero.
57.Sh SEE ALSO 50.Sh SEE ALSO
58.Xr bitstring 3 51.Xr bitstring 3
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c
index 42bc87ddea..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.
36static 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 */
44int 17int
45ffs(mask) 18ffs(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";*/
36static char *rcsid = "$Id: index.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 31#include <string.h>
40 32
41char * 33char *
42#ifdef STRCHR 34#ifdef STRCHR
43strchr(p, ch) 35strchr(const char *p, int ch)
44#else 36#else
45index(p, ch) 37index(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..ef53d95645 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.9 2007/05/31 19:19:32 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,14 +27,14 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)memccpy.3 5.4 (Berkeley) 4/19/91 30.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
33.\" $Id: memccpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
34.\" 31.\"
35.Dd April 19, 1991 32.Dd $Mdocdate: May 31 2007 $
36.Dt MEMCCPY 3 33.Dt MEMCCPY 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
39.Nm memccpy 36.Nm memccpy
37.Nd copy string until character found
40.Sh SYNOPSIS 38.Sh SYNOPSIS
41.Fd #include <string.h> 39.Fd #include <string.h>
42.Ft void * 40.Ft void *
@@ -44,14 +42,15 @@
44.Sh DESCRIPTION 42.Sh DESCRIPTION
45The 43The
46.Fn memccpy 44.Fn memccpy
47function 45function copies bytes from string
48copies bytes from string
49.Fa src 46.Fa src
50to string 47to string
51.Fa dst . 48.Fa dst .
52If the character 49If the character
53.Fa c 50.Fa c
54(as converted to an unsigned char) occurs in the string 51(as converted to an
52.Li unsigned char )
53occurs in the string
55.Fa src , 54.Fa src ,
56the copy stops and a pointer to the byte after the copy of 55the copy stops and a pointer to the byte after the copy of
57.Fa c 56.Fa c
@@ -60,14 +59,15 @@ in the string
60is returned. 59is returned.
61Otherwise, 60Otherwise,
62.Fa len 61.Fa len
63bytes are copied, and a NULL pointer is returned. 62bytes are copied, and a null pointer is returned.
64.Sh SEE ALSO 63.Sh SEE ALSO
65.Xr bcopy 3 , 64.Xr bcopy 3 ,
66.Xr memcpy 3 , 65.Xr memcpy 3 ,
67.Xr memmove 3 , 66.Xr memmove 3 ,
68.Xr strcpy 3 67.Xr strcpy 3 ,
68.Xr strlcpy 3
69.Sh HISTORY 69.Sh HISTORY
70The 70The
71.Fn memccpy 71.Fn memccpy
72function is 72function first appeared in
73.Ud . 73.Bx 4.4 .
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c
index 3a1d7bcca1..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";*/
36static 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
41void * 34void *
42memccpy(t, f, c, n) 35memccpy(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..558848ac23 100644
--- a/src/lib/libc/string/memchr.3
+++ b/src/lib/libc/string/memchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)memchr.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: memchr.3,v 1.9 2007/09/03 16:50:14 jmc Exp $
37.\" $Id: memchr.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: September 3 2007 $
40.Dt MEMCHR 3 35.Dt MEMCHR 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -46,26 +41,37 @@
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft void * 42.Ft void *
48.Fn memchr "const void *b" "int c" "size_t len" 43.Fn memchr "const void *b" "int c" "size_t len"
44.Ft void *
45.Fn memrchr "const void *b" "int c" "size_t len"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn memchr 48.Fn memchr
52function 49function locates the first occurrence of
53locates the first occurrence of 50.Fa c
51(converted to an
52.Li unsigned char )
53in string
54.Fa b .
55.Pp
56The
57.Fn memrchr
58function behaves like
59.Fn memchr ,
60except that it locates the last occurrence of
54.Fa c 61.Fa c
55(converted to an unsigned char)
56in string 62in string
57.Fa b . 63.Fa b .
58.Sh RETURN VALUES 64.Sh RETURN VALUES
59The 65The
60.Fn memchr 66.Fn memchr
61function 67and
62returns a pointer to the byte located, 68.Fn memrchr
63or NULL if no such byte exists within 69functions return a pointer to the byte located, or
70.Dv NULL
71if no such byte exists within
64.Fa len 72.Fa len
65bytes. 73bytes.
66.Sh SEE ALSO 74.Sh SEE ALSO
67.Xr index 3 ,
68.Xr rindex 3 ,
69.Xr strchr 3 , 75.Xr strchr 3 ,
70.Xr strcspn 3 , 76.Xr strcspn 3 ,
71.Xr strpbrk 3 , 77.Xr strpbrk 3 ,
@@ -77,6 +83,11 @@ bytes.
77.Sh STANDARDS 83.Sh STANDARDS
78The 84The
79.Fn memchr 85.Fn memchr
80function 86function conforms to
81conforms to
82.St -ansiC . 87.St -ansiC .
88.Pp
89The
90.Fn memrchr
91function is an
92.Ox
93extension.
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";*/
39static char *rcsid = "$Id: memchr.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <string.h> 34#include <string.h>
43 35
44void * 36void *
45memchr(s, c, n) 37memchr(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..8c35f388f2 100644
--- a/src/lib/libc/string/memcmp.3
+++ b/src/lib/libc/string/memcmp.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)memcmp.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memcmp.3,v 1.6 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: memcmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt MEMCMP 3 35.Dt MEMCMP 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memcmp 46.Fn memcmp
52function 47function compares byte string
53compares byte string
54.Fa b1 48.Fa b1
55against byte string 49against byte string
56.Fa b2 . 50.Fa b2 .
@@ -60,10 +54,11 @@ bytes long.
60.Sh RETURN VALUES 54.Sh RETURN VALUES
61The 55The
62.Fn memcmp 56.Fn memcmp
63function 57function returns zero if the two strings are identical,
64returns zero if the the two strings are identical,
65otherwise returns the difference between the first two differing bytes 58otherwise returns the difference between the first two differing bytes
66(treated as unsigned char values, so that 59(treated as
60.Li unsigned char
61values, so that
67.Sq Li \e200 62.Sq Li \e200
68is greater than 63is greater than
69.Sq Li \&\e0 , 64.Sq Li \&\e0 ,
@@ -78,6 +73,5 @@ Zero-length strings are always identical.
78.Sh STANDARDS 73.Sh STANDARDS
79The 74The
80.Fn memcmp 75.Fn memcmp
81function 76function conforms to
82conforms to
83.St -ansiC . 77.St -ansiC .
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c
index 23d2ab2393..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";*/
39static char *rcsid = "$Id: memcmp.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <string.h> 34#include <string.h>
43 35
44/* 36/*
45 * Compare memory regions. 37 * Compare memory regions.
46 */ 38 */
47int 39int
48memcmp(s1, s2, n) 40memcmp(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..1deb03631b 100644
--- a/src/lib/libc/string/memcpy.3
+++ b/src/lib/libc/string/memcpy.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memcpy.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memcpy.3,v 1.7 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: memcpy.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt MEMCPY 3 35.Dt MEMCPY 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm memcpy 38.Nm memcpy
44.Nd copy byte string 39.Nd copy bytes
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft void * 42.Ft void *
@@ -49,36 +44,34 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memcpy 46.Fn memcpy
52function 47function copies
53copies
54.Fa len 48.Fa len
55bytes from string 49bytes from buffer
56.Fa src 50.Fa src
57to string 51to buffer
58.Fa dst . 52.Fa dst .
59.Sh RETURN VALUES 53.Sh RETURN VALUES
60The 54The
61.Fn memcpy 55.Fn memcpy
62function 56function returns the original value of
63returns the original value of
64.Fa dst . 57.Fa dst .
65.Sh SEE ALSO 58.Sh SEE ALSO
66.Xr bcopy 3 , 59.Xr bcopy 3 ,
67.Xr memccpy 3 , 60.Xr memccpy 3 ,
68.Xr memmove 3 , 61.Xr memmove 3 ,
69.Xr strcpy 3 62.Xr strcpy 3 ,
63.Xr strlcpy 3
70.Sh STANDARDS 64.Sh STANDARDS
71The 65The
72.Fn memcpy 66.Fn memcpy
73function 67function conforms to
74conforms to
75.St -ansiC . 68.St -ansiC .
76.Sh BUGS 69.Sh BUGS
77In this implementation 70In this implementation
78.Fn memcpy 71.Fn memcpy
79is implemented using 72is implemented using
80.Xr bcopy 3 , 73.Xr bcopy 3 ,
81and therefore the strings may overlap. 74and therefore the buffers may overlap.
82On other systems, copying overlapping strings may produce surprises. 75On other systems, copying overlapping buffers may produce surprises.
83A simpler solution is to not use 76A simpler solution is to not use
84.Fn memcpy . 77.Fn memcpy .
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3
index 24422e7971..c6e3912669 100644
--- a/src/lib/libc/string/memmove.3
+++ b/src/lib/libc/string/memmove.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)memmove.3 5.5 (Berkeley) 6/29/91 32.\" $OpenBSD: memmove.3,v 1.7 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: memmove.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt MEMMOVE 3 35.Dt MEMMOVE 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm memmove 38.Nm memmove
44.Nd copy byte string 39.Nd copy bytes
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft void * 42.Ft void *
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memmove 46.Fn memmove
52function 47function copies
53copies
54.Fa len 48.Fa len
55bytes from string 49bytes from buffer
56.Fa src 50.Fa src
57to string 51to buffer
58.Fa dst . 52.Fa dst .
59The two strings may overlap; 53The two buffers may overlap;
60the copy is always done in a non-destructive manner. 54the copy is always done in a non-destructive manner.
61.Sh RETURN VALUES 55.Sh RETURN VALUES
62The 56The
@@ -67,10 +61,10 @@ function returns the original value of
67.Xr bcopy 3 , 61.Xr bcopy 3 ,
68.Xr memccpy 3 , 62.Xr memccpy 3 ,
69.Xr memcpy 3 , 63.Xr memcpy 3 ,
70.Xr strcpy 3 64.Xr strcpy 3 ,
65.Xr strlcpy 3
71.Sh STANDARDS 66.Sh STANDARDS
72The 67The
73.Fn memmove 68.Fn memmove
74function 69function conforms to
75conforms to
76.St -ansiC . 70.St -ansiC .
diff --git a/src/lib/libc/string/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 */
25void *
26memrchr(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..7799b5e2d2 100644
--- a/src/lib/libc/string/memset.3
+++ b/src/lib/libc/string/memset.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)memset.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: memset.3,v 1.6 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: memset.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt MEMSET 3 35.Dt MEMSET 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,12 +44,18 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn memset 46.Fn memset
52function 47function writes
53writes
54.Fa len 48.Fa len
55bytes of value 49bytes of value
56.Fa c 50.Fa c
57(converted to an unsigned char) to the string 51(converted to an
52.Li unsigned char )
53to the string
54.Fa b .
55.Sh RETURN VALUES
56The
57.Fn memset
58function returns the original value of
58.Fa b . 59.Fa b .
59.Sh SEE ALSO 60.Sh SEE ALSO
60.Xr bzero 3 , 61.Xr bzero 3 ,
@@ -62,6 +63,5 @@ bytes of value
62.Sh STANDARDS 63.Sh STANDARDS
63The 64The
64.Fn memset 65.Fn memset
65function 66function conforms to
66conforms to
67.St -ansiC . 67.St -ansiC .
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c
index 117de2e80b..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";*/
39static char *rcsid = "$Id: memset.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <string.h> 34#include <string.h>
43 35
44void * 36void *
45memset(dst, c, n) 37memset(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";*/
36static char *rcsid = "$Id: rindex.c,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 31#include <string.h>
40 32
41char * 33char *
42#ifdef STRRCHR 34#ifdef STRRCHR
43strrchr(p, ch) 35strrchr(const char *p, int ch)
44#else 36#else
45rindex(p, ch) 37rindex(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/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3
index 46e9010e4f..c17aa694d1 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.10 2007/05/31 19:19:32 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" This code is derived from software contributed to Berkeley by 6.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek. 7.\" Chris Torek.
@@ -11,11 +13,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 18.\" without specific prior written permission.
21.\" 19.\"
@@ -31,14 +29,14 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
33.\" 31.\"
34.\" from: @(#)strcasecmp.3 5.4 (Berkeley) 4/19/91 32.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
35.\" $Id: strcasecmp.3,v 1.1.1.1 1995/10/18 08:42:21 deraadt Exp $
36.\" 33.\"
37.Dd April 19, 1991 34.Dd $Mdocdate: May 31 2007 $
38.Dt STRCASECMP 3 35.Dt STRCASECMP 3
39.Os 36.Os
40.Sh NAME 37.Sh NAME
41.Nm strcasecmp 38.Nm strcasecmp ,
39.Nm strncasecmp
42.Nd compare strings, ignoring case 40.Nd compare strings, ignoring case
43.Sh SYNOPSIS 41.Sh SYNOPSIS
44.Fd #include <string.h> 42.Fd #include <string.h>
@@ -51,13 +49,12 @@ The
51.Fn strcasecmp 49.Fn strcasecmp
52and 50and
53.Fn strncasecmp 51.Fn strncasecmp
54functions 52functions compare the NUL-terminated strings
55compare the null-terminated strings
56.Fa s1 53.Fa s1
57and 54and
58.Fa s2 55.Fa s2
59and return an integer greater than, equal to, or less than 0, 56and return an integer greater than, equal to, or less than 0,
60according as 57according to whether
61.Fa s1 58.Fa s1
62is lexicographically greater than, equal to, or less than 59is lexicographically greater than, equal to, or less than
63.Fa s2 60.Fa s2
@@ -68,7 +65,6 @@ The comparison is done using unsigned characters, so that
68is greater than 65is greater than
69.Ql \e0 . 66.Ql \e0 .
70.Pp 67.Pp
71The
72.Fn strncasecmp 68.Fn strncasecmp
73compares at most 69compares at most
74.Fa len 70.Fa len
@@ -84,5 +80,5 @@ The
84.Fn strcasecmp 80.Fn strcasecmp
85and 81and
86.Fn strncasecmp 82.Fn strncasecmp
87functions are 83functions first appeared in
88.Ud . 84.Bx 4.4 .
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c
index 79bd0081e3..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";*/
36static 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
41typedef unsigned char u_char; 34typedef unsigned char u_char;
@@ -81,12 +74,11 @@ static const u_char charmap[] = {
81}; 74};
82 75
83int 76int
84strcasecmp(s1, s2) 77strcasecmp(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
97int 89int
98strncasecmp(s1, s2, n) 90strncasecmp(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/string/strcasestr.c b/src/lib/libc/string/strcasestr.c
new file mode 100644
index 0000000000..aa74c0176d
--- /dev/null
+++ b/src/lib/libc/string/strcasestr.c
@@ -0,0 +1,60 @@
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 $ */
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 <ctype.h>
37#include <string.h>
38
39/*
40 * Find the first occurrence of find in s, ignore case.
41 */
42char *
43strcasestr(const char *s, const char *find)
44{
45 char c, sc;
46 size_t len;
47
48 if ((c = *find++) != 0) {
49 c = (char)tolower((unsigned char)c);
50 len = strlen(find);
51 do {
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);
60}
diff --git a/src/lib/libc/string/strcat.3 b/src/lib/libc/string/strcat.3
index 5357d65754..4068db752c 100644
--- a/src/lib/libc/string/strcat.3
+++ b/src/lib/libc/string/strcat.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcat.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcat.3,v 1.12 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strcat.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRCAT 3 35.Dt STRCAT 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcat 38.Nm strcat ,
39.Nm strncat
44.Nd concatenate strings 40.Nd concatenate strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,10 +49,9 @@ The
53.Fn strcat 49.Fn strcat
54and 50and
55.Fn strncat 51.Fn strncat
56functions 52functions append a copy of the NUL-terminated string
57append a copy of the null-terminated string
58.Fa append 53.Fa append
59to the end of the null-terminated string 54to the end of the NUL-terminated string
60.Fa s , 55.Fa s ,
61then add a terminating 56then add a terminating
62.Ql \e0 . 57.Ql \e0 .
@@ -66,29 +61,73 @@ must have sufficient space to hold the result.
66.Pp 61.Pp
67The 62The
68.Fn strncat 63.Fn strncat
69function 64function appends not more than
70appends not more than
71.Fa count 65.Fa count
72characters. 66characters where space for the terminating
67.Ql \e0
68should not be included in
69.Fa count .
73.Sh RETURN VALUES 70.Sh RETURN VALUES
74The 71The
75.Fn strcat 72.Fn strcat
76and 73and
77.Fn strncat 74.Fn strncat
78functions 75functions return the pointer
79return the pointer
80.Fa s . 76.Fa s .
77.Sh EXAMPLES
78The following appends
79.Dq Li abc
80to
81.Va chararray :
82.Bd -literal -offset indent
83char *letters = "abcdefghi";
84
85(void)strncat(chararray, letters, 3);
86.Ed
87.Pp
88The following example shows how to use
89.Fn strncat
90safely in conjunction with
91.Xr strncpy 3 .
92.Bd -literal -offset indent
93char buf[BUFSIZ];
94char *input, *suffix;
95
96(void)strncpy(buf, input, sizeof(buf) - 1);
97buf[sizeof(buf) - 1] = '\e0';
98(void)strncat(buf, suffix, sizeof(buf) - 1 - strlen(buf));
99.Ed
100.Pp
101The above will copy as many characters from
102.Va input
103to
104.Va buf
105as will fit.
106It then appends as many characters from
107.Va suffix
108as will fit (or none
109if there is no space).
110For operations like this, the
111.Xr strlcpy 3
112and
113.Xr strlcat 3
114functions are a better choice, as shown below.
115.Bd -literal -offset indent
116(void)strlcpy(buf, input, sizeof(buf));
117(void)strlcat(buf, suffix, sizeof(buf));
118.Ed
81.Sh SEE ALSO 119.Sh SEE ALSO
82.Xr bcopy 3 , 120.Xr bcopy 3 ,
83.Xr memccpy 3 , 121.Xr memccpy 3 ,
84.Xr memcpy 3 , 122.Xr memcpy 3 ,
85.Xr memmove 3 , 123.Xr memmove 3 ,
86.Xr strcpy 3 124.Xr strcpy 3 ,
125.Xr strlcat 3 ,
126.Xr strlcpy 3
87.Sh STANDARDS 127.Sh STANDARDS
88The 128The
89.Fn strcat 129.Fn strcat
90and 130and
91.Fn strncat 131.Fn strncat
92functions 132functions conform to
93conform to
94.St -ansiC . 133.St -ansiC .
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";*/
36static char *rcsid = "$Id: strcat.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
41char * 43char *
42strcat(s, append) 44strcat(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..6a9de9604e 100644
--- a/src/lib/libc/string/strchr.3
+++ b/src/lib/libc/string/strchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,29 +29,29 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strchr.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strchr.3,v 1.9 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strchr.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRCHR 3 35.Dt STRCHR 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strchr 38.Nm strchr ,
44.Nd locate character in string 39.Nm index
40.Nd locate first occurrence of a character in a string
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
47.Ft char * 43.Ft char *
48.Fn strchr "const char *s" "int c" 44.Fn strchr "const char *s" "int c"
45.Ft char *
46.Fn index "const char *s" "int c"
49.Sh DESCRIPTION 47.Sh DESCRIPTION
50The 48The
51.Fn strchr 49.Fn strchr
52function locates the first occurrence of 50function locates the first occurrence of the character
53.Ar c 51.Fa c
54in the string pointed to by 52in the string
55.Ar s . 53.Fa s .
56The terminating 54The terminating NUL character is considered part of the string.
57.Dv NULL
58character is considered part of the string.
59If 55If
60.Fa c 56.Fa c
61is 57is
@@ -63,16 +59,31 @@ is
63.Fn strchr 59.Fn strchr
64locates the terminating 60locates the terminating
65.Ql \e0 . 61.Ql \e0 .
62.Pp
63The
64.Fn index
65function is an old synonym for
66.Fn strchr .
66.Sh RETURN VALUES 67.Sh RETURN VALUES
67The function 68The
68.Fn strchr 69.Fn strchr
69returns a pointer to the located character, or 70function returns a pointer to the located character or
70.Dv NULL 71.Dv NULL
71if the character does not appear in the string. 72if the character does not appear in the string.
73.Sh EXAMPLES
74After the following call to
75.Fn strchr ,
76.Va p
77will point to the string
78.Qq oobar :
79.Bd -literal -offset indent
80char *p;
81char *s = "foobar";
82
83p = strchr(s, 'o');
84.Ed
72.Sh SEE ALSO 85.Sh SEE ALSO
73.Xr index 3 ,
74.Xr memchr 3 , 86.Xr memchr 3 ,
75.Xr rindex 3 ,
76.Xr strcspn 3 , 87.Xr strcspn 3 ,
77.Xr strpbrk 3 , 88.Xr strpbrk 3 ,
78.Xr strrchr 3 , 89.Xr strrchr 3 ,
@@ -83,6 +94,9 @@ if the character does not appear in the string.
83.Sh STANDARDS 94.Sh STANDARDS
84The 95The
85.Fn strchr 96.Fn strchr
86function 97function conforms to
87conforms to
88.St -ansiC . 98.St -ansiC .
99.Pp
100The
101.Fn index
102function is deprecated and shouldn't be used in new code.
diff --git a/src/lib/libc/string/strcmp.3 b/src/lib/libc/string/strcmp.3
index fecaa85410..73cd5b40d8 100644
--- a/src/lib/libc/string/strcmp.3
+++ b/src/lib/libc/string/strcmp.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcmp.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcmp.3,v 1.9 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strcmp.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRCMP 3 35.Dt STRCMP 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcmp 38.Nm strcmp ,
39.Nm strncmp
44.Nd compare strings 40.Nd compare strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,8 +49,7 @@ The
53.Fn strcmp 49.Fn strcmp
54and 50and
55.Fn strncmp 51.Fn strncmp
56functions 52functions lexicographically compare the NUL-terminated strings
57lexicographically compare the null-terminated strings
58.Fa s1 53.Fa s1
59and 54and
60.Fa s2 . 55.Fa s2 .
@@ -64,7 +59,7 @@ The
64and 59and
65.Fn strncmp 60.Fn strncmp
66return an integer greater than, equal to, or less than 0, according 61return an integer greater than, equal to, or less than 0, according
67as the string 62to whether the string
68.Fa s1 63.Fa s1
69is greater than, equal to, or less than the string 64is greater than, equal to, or less than the string
70.Fa s2 . 65.Fa s2 .
@@ -73,9 +68,8 @@ The comparison is done using unsigned characters, so that
73is greater than 68is greater than
74.Ql \e0 . 69.Ql \e0 .
75.Pp 70.Pp
76The
77.Fn strncmp 71.Fn strncmp
78compares not more than 72compares at most
79.Fa len 73.Fa len
80characters. 74characters.
81.Sh SEE ALSO 75.Sh SEE ALSO
@@ -89,6 +83,5 @@ The
89.Fn strcmp 83.Fn strcmp
90and 84and
91.Fn strncmp 85.Fn strncmp
92functions 86functions conform to
93conform to
94.St -ansiC . 87.St -ansiC .
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c
index ae19e2e26e..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";*/
39static char *rcsid = "$Id: strcmp.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
47int 44int
48strcmp(s1, s2) 45strcmp(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..ea7452a749 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,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: @(#)strcoll.3 5.6 (Berkeley) 6/29/91 32.\" $OpenBSD: strcoll.3,v 1.7 2007/05/31 19:19:32 jmc 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: May 31 2007 $
40.Dt STRCOLL 3 35.Dt STRCOLL 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,14 +44,13 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strcoll 46.Fn strcoll
52function 47function lexicographically compares the NUL-terminated strings
53lexicographically compares the null-terminated strings
54.Fa s1 48.Fa s1
55and 49and
56.Fa s2 50.Fa s2
57according to the current locale collation 51according to the current locale collation
58and returns an integer greater than, equal to, or less than 0, 52and returns an integer greater than, equal to, or less than 0,
59according as 53according to whether
60.Fa s1 54.Fa s1
61is greater than, equal to, or less than 55is greater than, equal to, or less than
62.Fa s2 . 56.Fa s2 .
@@ -70,6 +64,5 @@ is greater than, equal to, or less than
70.Sh STANDARDS 64.Sh STANDARDS
71The 65The
72.Fn strcoll 66.Fn strcoll
73function 67function conforms to
74conforms to
75.St -ansiC . 68.St -ansiC .
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c
index 86c742cba9..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";*/
39static char *rcsid = "$Id: strcoll.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
47int 39int
48strcoll(s1, s2) 40strcoll(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..428e474d43 100644
--- a/src/lib/libc/string/strcpy.3
+++ b/src/lib/libc/string/strcpy.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,14 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strcpy.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strcpy.3,v 1.15 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strcpy.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRCPY 3 35.Dt STRCPY 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strcpy 38.Nm strcpy ,
39.Nm strncpy
44.Nd copy strings 40.Nd copy strings
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
@@ -53,8 +49,7 @@ The
53.Fn strcpy 49.Fn strcpy
54and 50and
55.Fn strncpy 51.Fn strncpy
56functions 52functions copy the string
57copy the string
58.Fa src 53.Fa src
59to 54to
60.Fa dst 55.Fa dst
@@ -62,7 +57,6 @@ to
62.Ql \e0 57.Ql \e0
63character). 58character).
64.Pp 59.Pp
65The
66.Fn strncpy 60.Fn strncpy
67copies not more than 61copies not more than
68.Fa len 62.Fa len
@@ -78,45 +72,80 @@ characters long, and
78.Em not 72.Em not
79terminating 73terminating
80.Fa dst 74.Fa dst
81if 75if the length of
82.Fa src 76.Fa src
83is more than 77is greater than or equal to
84.Fa len 78.Fa len .
85characters long.
86.Sh RETURN VALUES 79.Sh RETURN VALUES
87The 80The
88.Fn strcpy 81.Fn strcpy
89and 82and
90.Fn strncpy 83.Fn strncpy
91functions 84functions return
92return
93.Fa dst . 85.Fa dst .
94.Sh EXAMPLES 86.Sh EXAMPLES
95The following sets 87The following sets
96.Dq Li chararray 88.Va chararray
97to 89to
98.Dq Li abc\e0\e0\e0 : 90.Dq abc\e0\e0\e0 :
99.Bd -literal -offset indent 91.Bd -literal -offset indent
100(void)strncpy(chararray, "abc", 6). 92(void)strncpy(chararray, "abc", 6);
101.Ed 93.Ed
102.Pp 94.Pp
103The following sets 95The following sets
104.Dq Li chararray 96.Va chararray
105to 97to
106.Dq Li abcdef : 98.Dq abcdef
99and does
100.Em not
101NUL terminate
102.Va chararray
103because the length of the source string is greater than or equal to the
104length parameter.
105.Fn strncpy
106.Em only
107NUL terminates the destination string when the length of the source
108string is less than the length parameter.
107.Bd -literal -offset indent 109.Bd -literal -offset indent
108(void)strncpy(chararray, "abcdefgh", 6); 110(void)strncpy(chararray, "abcdefgh", 6);
109.Ed 111.Ed
112.Pp
113The following copies as many characters from
114.Va input
115to
116.Va buf
117as will fit and NUL terminates the result.
118Because
119.Fn strncpy
120does
121.Em not
122guarantee to NUL terminate the string itself, it must be done by hand.
123.Bd -literal -offset indent
124char buf[BUFSIZ];
125
126(void)strncpy(buf, input, sizeof(buf) - 1);
127buf[sizeof(buf) - 1] = '\e0';
128.Ed
129.Pp
130Note that
131.Xr strlcpy 3
132is a better choice for this kind of operation.
133The equivalent using
134.Xr strlcpy 3
135is simply:
136.Bd -literal -offset indent
137(void)strlcpy(buf, input, sizeof(buf));
138.Ed
110.Sh SEE ALSO 139.Sh SEE ALSO
111.Xr bcopy 3 , 140.Xr bcopy 3 ,
112.Xr memccpy 3 , 141.Xr memccpy 3 ,
113.Xr memcpy 3 , 142.Xr memcpy 3 ,
114.Xr memmove 3 143.Xr memmove 3 ,
144.Xr strlcpy 3
115.Sh STANDARDS 145.Sh STANDARDS
116The 146The
117.Fn strcpy 147.Fn strcpy
118and 148and
119.Fn strncpy 149.Fn strncpy
120functions 150functions conform to
121conform to
122.St -ansiC . 151.St -ansiC .
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";*/
36static char *rcsid = "$Id: strcpy.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
41char * 43char *
42strcpy(to, from) 44strcpy(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..21c727344d 100644
--- a/src/lib/libc/string/strcspn.3
+++ b/src/lib/libc/string/strcspn.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)strcspn.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strcspn.3,v 1.9 2007/08/08 07:20:45 ray Exp $
37.\" $Id: strcspn.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: August 8 2007 $
40.Dt STRCSPN 3 35.Dt STRCSPN 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,27 +44,48 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strcspn 46.Fn strcspn
52function 47function spans the initial part of the NUL-terminated string
53spans the initial part of the null-terminated string
54.Fa s 48.Fa s
55as long as the characters from 49as long as the characters from
56.Fa s 50.Fa s
57do not occur in string 51do not occur in string
58.Fa charset 52.Fa charset
59(it 53(it spans the
60spans the
61.Em complement 54.Em complement
62of 55of
63.Fa charset ) . 56.Fa charset ) .
64.Sh RETURN VALUES 57.Sh RETURN VALUES
65The 58The
66.Fn strcspn 59.Fn strcspn
67function 60function returns the number of characters spanned.
68returns the number of characters spanned. 61.Sh EXAMPLES
62The following call to
63.Fn strcspn
64will return 3, since the first three characters of string
65.Fa s
66do not occur in string
67.Fa charset :
68.Bd -literal -offset indent
69char *s = "foobar";
70char *charset = "bar";
71size_t span;
72
73span = strcspn(s, charset);
74.Ed
75.Pp
76The following removes the first (if any) newline character from string
77.Fa line .
78This is useful for trimming the newline after a
79.Xr fgets 3
80call.
81.Bd -literal -offset indent
82char line[BUFSIZ];
83
84if (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 ,
@@ -80,6 +96,5 @@ returns the number of characters spanned.
80.Sh STANDARDS 96.Sh STANDARDS
81The 97The
82.Fn strcspn 98.Fn strcspn
83function 99function conforms to
84conforms to
85.St -ansiC . 100.St -ansiC .
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";*/
39static char *rcsid = "$Id: strcspn.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
47size_t 39size_t
48strcspn(s1, s2) 40strcspn(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..5ef38e38f3 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.14 2007/05/31 19:19:32 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,10 +27,9 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)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: May 31 2007 $
36.Dt STRDUP 3 33.Dt STRDUP 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
@@ -41,25 +38,47 @@
41.Sh SYNOPSIS 38.Sh SYNOPSIS
42.Fd #include <string.h> 39.Fd #include <string.h>
43.Ft char * 40.Ft char *
44.Fn strdup "const char *str" 41.Fn strdup "const char *s"
45.Sh DESCRIPTION 42.Sh DESCRIPTION
46The 43The
47.Fn strdup 44.Fn strdup
48function 45function allocates sufficient memory for a copy of the string
49allocates sufficient memory for a copy 46.Fa s ,
50of the string
51.Fa str ,
52does the copy, and returns a pointer to it. 47does the copy, and returns a pointer to it.
53The pointer may subsequently be used as an 48The pointer may subsequently be used as an argument to the function
54argument to the function
55.Xr free 3 . 49.Xr free 3 .
50.Pp
51If insufficient memory is available,
52.Dv NULL
53is returned.
54.Sh EXAMPLES
55The following will point
56.Va p
57to an allocated area of memory containing the NUL-terminated string
58.Qq foobar :
59.Bd -literal -offset indent
60char *p;
61
62if ((p = strdup("foobar")) == NULL) {
63 fprintf(stderr, "Out of memory.\en");
64 exit(1);
65}
66.Ed
67.Sh ERRORS
68The
69.Fn strdup
70function may fail and set the external variable
71.Va errno
72for any of the errors specified for the library function
73.Xr malloc 3 .
56.Sh SEE ALSO 74.Sh SEE ALSO
57.Xr free 3 , 75.Xr free 3 ,
58.Xr malloc 3 , 76.Xr malloc 3 ,
59.Xt strcpy 3 , 77.Xr strcpy 3 ,
60.Xt strlen 3 78.Xr strlcpy 3 ,
79.Xr strlen 3
61.Sh HISTORY 80.Sh HISTORY
62The 81The
63.Fn strdup 82.Fn strdup
64function 83function first appeared in
65.Ud . 84.Bx 4.4 .
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c
index 27ede44110..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";*/
36static 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
42char * 38char *
43strdup(str) 39strdup(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..84c64c10bb 100644
--- a/src/lib/libc/string/strerror.3
+++ b/src/lib/libc/string/strerror.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,12 +29,11 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 32.\" $OpenBSD: strerror.3,v 1.9 2007/05/31 19:19:32 jmc 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: May 31 2007 $
40.Dt STRERROR 3 35.Dt STRERROR 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strerror 38.Nm strerror
44.Nd get error message string 39.Nd get error message string
@@ -46,15 +41,63 @@
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft char * 42.Ft char *
48.Fn strerror "int errnum" 43.Fn strerror "int errnum"
44.Ft int
45.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
49.Sh DESCRIPTION 46.Sh DESCRIPTION
50The 47The
51.Fn strerror 48.Fn strerror
52function returns a pointer to the language-dependent error message 49and
53string affiliated with an error number. 50.Fn strerror_r
51functions map the error number
52.Fa errnum
53to a language-dependent error message string.
54.Pp 54.Pp
55The array pointed to is not to be modified by the program, but may be 55.Fn strerror
56overwritten by subsequent calls to 56returns a string containing a maximum of
57.Dv NL_TEXTMAX
58characters, including the trailing NUL.
59This string is not to be modified by the calling program,
60but may be overwritten by subsequent calls to
57.Fn strerror . 61.Fn strerror .
62.Pp
63.Fn strerror_r
64is a thread safe version of
65.Fn strerror
66that places the error message in the specified buffer
67.Fa strerrbuf .
68.Sh RETURN VALUES
69.Fn strerror
70returns a pointer to the error message string.
71If an error occurs, the error code is stored in
72.Va errno .
73.Pp
74.Fn strerror_r
75returns zero upon successful completion.
76If an error occurs, the error code is stored in
77.Va errno
78and the error code is returned.
79.Sh ERRORS
80.Fn strerror
81and
82.Fn strerror_r
83may fail if:
84.Bl -tag -width Er
85.It Bq Er EINVAL
86.Fa errnum
87is not a valid error number.
88The returned error string will consist of an error message that includes
89.Fa errnum .
90.El
91.Pp
92.Fn strerror_r
93may fail if:
94.Bl -tag -width Er
95.It Bq Er ERANGE
96The error message is larger than
97.Fa buflen
98characters.
99The message will be truncated to fit.
100.El
58.Sh SEE ALSO 101.Sh SEE ALSO
59.Xr intro 2 , 102.Xr intro 2 ,
60.Xr perror 3 , 103.Xr perror 3 ,
@@ -64,3 +107,7 @@ The
64.Fn strerror 107.Fn strerror
65function conforms to 108function conforms to
66.St -ansiC . 109.St -ansiC .
110The
111.Fn strerror_r
112function conforms to
113.St -p1003.1 .
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";*/
36static char *rcsid = "$Id: strerror.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
48extern char *__strerror __P((int, char *));
49
50char * 34char *
51strerror(num) 35strerror(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..aa63408ab8
--- /dev/null
+++ b/src/lib/libc/string/strerror_r.c
@@ -0,0 +1,137 @@
1/* $OpenBSD: strerror_r.c,v 1.7 2007/03/01 16:29:09 bluhm 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
20static 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
33static 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
69static 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", 0);
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
114int
115strerror_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
131char *
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
50The
51.Fn strftime
52function formats the information from
53.Fa timeptr
54into the buffer
55.Fa buf
56according to the string pointed to by
57.Fa format .
58.Pp
59The
60.Fa format
61string consists of zero or more conversion specifications and
62ordinary characters.
63All ordinary characters are copied directly into the buffer.
64A conversion specification consists of a percent sign
65.Ql %
66and one other character.
67.Pp
68No more than
69.Fa maxsize
70characters will be placed into the array.
71If the total number of resulting characters, including the terminating
72null character, is not more than
73.Fa maxsize ,
74.Fn strftime
75returns the number of characters in the array, not counting the
76terminating null.
77Otherwise, zero is returned.
78.Pp
79Each conversion specification is replaced by the characters as
80follows which are then copied into the buffer.
81.Bl -tag -width "xxxx"
82.It Cm \&%A
83is replaced by the locale's full weekday name.
84.It Cm %a
85is replaced by the locale's abbreviated weekday name.
86.It Cm \&%B
87is replaced by the locale's full month name.
88.It Cm \&%b No or Cm \&%h
89is replaced by the locale's abbreviated month name.
90.It Cm \&%C
91is replaced by the century (a year divided by 100 and truncated to an integer)
92as a decimal number (00-99).
93.It Cm \&%c
94is replaced by the locale's appropriate date and time representation.
95.It Cm \&%D
96is replaced by the date in the format
97.Dq Li %m/%d/%y .
98.It Cm \&%d
99is replaced by the day of the month as a decimal number (01-31).
100.It Cm \&%e
101is replaced by the day of month as a decimal number (1-31);
102single digits are preceded by a blank.
103.It Cm \&%H
104is replaced by the hour (24-hour clock) as a decimal number (00-23).
105.It Cm \&%I
106is replaced by the hour (12-hour clock) as a decimal number (01-12).
107.It Cm \&%j
108is replaced by the day of the year as a decimal number (001-366).
109.It Cm \&%k
110is replaced by the hour (24-hour clock) as a decimal number (0-23);
111single digits are preceded by a blank.
112.It Cm \&%l
113is replaced by the hour (12-hour clock) as a decimal number (1-12);
114single digits are preceded by a blank.
115.It Cm \&%M
116is replaced by the minute as a decimal number (00-59).
117.It Cm %m
118is replaced by the month as a decimal number (01-12).
119.It Cm %n
120is replaced by a newline.
121.It Cm %p
122is replaced by the locale's equivalent of either
123.Dq Tn AM
124or
125.Dq Tn PM .
126.It Cm \&%R
127is replaced by the time in the format
128.Dq Li %H:%M .
129.It Cm \&%r
130is replaced by the locale's representation of 12-hour clock time
131using AM/PM notation.
132.It Cm \&%T
133is replaced by the time in the format
134.Dq Li %H:%M:%S .
135.It Cm \&%t
136is replaced by a tab.
137.It Cm \&%S
138is replaced by the second as a decimal number (00-60).
139.It Cm %s
140is replaced by the number of seconds since the Epoch, UCT (see
141.Xr mktime 3 ) .
142.It Cm \&%U
143is replaced by the week number of the year (Sunday as the first day of
144the week) as a decimal number (00-53).
145.It Cm \&%u
146is replaced by the weekday (Monday as the first day of the week)
147as a decimal number (1-7).
148.It Cm \&%V
149is replaced by the week number of the year (Monday as the first day of
150the week) as a decimal number (01-53). If the week containing January
1511 has four or more days in the new year, then it is week 1; otherwise
152it is week 53 of the previous year, and the next week is week 1.
153.It Cm \&%W
154is replaced by the week number of the year (Monday as the first day of
155the week) as a decimal number (00-53).
156.It Cm \&%w
157is replaced by the weekday (Sunday as the first day of the week)
158as a decimal number (0-6).
159.It Cm \&%X
160is replaced by the locale's appropriate date representation.
161.It Cm \&%x
162is replaced by the locale's appropriate time representation.
163.It Cm \&%Y
164is replaced by the year with century as a decimal number.
165.It Cm \&%y
166is replaced by the year without century as a decimal number (00-99).
167.It Cm \&%Z
168is replaced by the time zone name.
169.It Cm %%
170is replaced by
171.Ql % .
172.El
173.Sh SEE ALSO
174.Xr date 1 ,
175.Xr ctime 3 ,
176.Xr printf 1 ,
177.Xr printf 3
178.Sh STANDARDS
179The
180.Fn strftime
181function
182conforms to
183.St -ansiC .
184The
185.Ql \&%C ,
186.Ql \&%D ,
187.Ql \&%e ,
188.Ql \&%h ,
189.Ql \&%k ,
190.Ql \&%l ,
191.Ql \&%n ,
192.Ql \&%r ,
193.Ql \&%R ,
194.Ql \&%s .
195.Ql \&%t ,
196.Ql \&%T ,
197.Ql \&%u ,
198and
199.Ql \&%V
200conversion specifications are extensions.
201.Sh BUGS
202There is no conversion specification for the phase of the moon.
diff --git a/src/lib/libc/string/strftime.c b/src/lib/libc/string/strftime.c
deleted file mode 100644
index fffa9ecbb0..0000000000
--- a/src/lib/libc/string/strftime.c
+++ /dev/null
@@ -1,317 +0,0 @@
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strftime.c 5.11 (Berkeley) 2/24/91";*/
36static char *rcsid = "$Id: strftime.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <sys/localedef.h>
40#include <locale.h>
41#include <string.h>
42#include <tzfile.h>
43#include <time.h>
44
45static size_t gsize;
46static char *pt;
47static int _add(), _conv(), _secs();
48static size_t _fmt();
49
50size_t
51strftime(s, maxsize, format, t)
52 char *s;
53 size_t maxsize;
54 const char *format;
55 const struct tm *t;
56{
57 tzset();
58
59 pt = s;
60 if ((gsize = maxsize) < 1)
61 return(0);
62 if (_fmt(format, t)) {
63 *pt = '\0';
64 return(maxsize - gsize);
65 }
66 return(0);
67}
68
69#define SUN_WEEK(t) (((t)->tm_yday + 7 - \
70 ((t)->tm_wday)) / 7)
71#define MON_WEEK(t) (((t)->tm_yday + 7 - \
72 ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
73static size_t
74_fmt(format, t)
75 register char *format;
76 struct tm *t;
77{
78 for (; *format; ++format) {
79 if (*format == '%') {
80 ++format;
81 if (*format == 'E') {
82 /* Alternate Era */
83 ++format;
84 } else if (*format == 'O') {
85 /* Alternate numeric symbols */
86 ++format;
87 }
88 switch(*format) {
89 case '\0':
90 --format;
91 break;
92 case 'A':
93 if (t->tm_wday < 0 || t->tm_wday > 6)
94 return(0);
95 if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
96 return(0);
97 continue;
98 case 'a':
99 if (t->tm_wday < 0 || t->tm_wday > 6)
100 return(0);
101 if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
102 return(0);
103 continue;
104 case 'B':
105 if (t->tm_mon < 0 || t->tm_mon > 11)
106 return(0);
107 if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
108 return(0);
109 continue;
110 case 'b':
111 case 'h':
112 if (t->tm_mon < 0 || t->tm_mon > 11)
113 return(0);
114 if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
115 return(0);
116 continue;
117 case 'C':
118 if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
119 2, '0'))
120 return(0);
121 continue;
122 case 'c':
123 if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
124 return(0);
125 continue;
126 case 'D':
127 if (!_fmt("%m/%d/%y", t))
128 return(0);
129 continue;
130 case 'd':
131 if (!_conv(t->tm_mday, 2, '0'))
132 return(0);
133 continue;
134 case 'e':
135 if (!_conv(t->tm_mday, 2, ' '))
136 return(0);
137 continue;
138 case 'H':
139 if (!_conv(t->tm_hour, 2, '0'))
140 return(0);
141 continue;
142 case 'I':
143 if (!_conv(t->tm_hour % 12 ?
144 t->tm_hour % 12 : 12, 2, '0'))
145 return(0);
146 continue;
147 case 'j':
148 if (!_conv(t->tm_yday + 1, 3, '0'))
149 return(0);
150 continue;
151 case 'k':
152 if (!_conv(t->tm_hour, 2, ' '))
153 return(0);
154 continue;
155 case 'l':
156 if (!_conv(t->tm_hour % 12 ?
157 t->tm_hour % 12: 12, 2, ' '))
158 return(0);
159 continue;
160 case 'M':
161 if (!_conv(t->tm_min, 2, '0'))
162 return(0);
163 continue;
164 case 'm':
165 if (!_conv(t->tm_mon + 1, 2, '0'))
166 return(0);
167 continue;
168 case 'n':
169 if (!_add("\n"))
170 return(0);
171 continue;
172 case 'p':
173 if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
174 return(0);
175 continue;
176 case 'R':
177 if (!_fmt("%H:%M", t))
178 return(0);
179 continue;
180 case 'r':
181 if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
182 return(0);
183 continue;
184 case 'S':
185 if (!_conv(t->tm_sec, 2, '0'))
186 return(0);
187 continue;
188 case 's':
189 if (!_secs(t))
190 return(0);
191 continue;
192 case 'T':
193 if (!_fmt("%H:%M:%S", t))
194 return(0);
195 continue;
196 case 't':
197 if (!_add("\t"))
198 return(0);
199 continue;
200 case 'U':
201 if (!_conv(SUN_WEEK(t), 2, '0'))
202 return(0);
203 continue;
204 case 'u':
205 if (!_conv(t->tm_wday ? t->tm_wday : 7, 2, '0'))
206 return(0);
207 continue;
208 case 'V':
209 {
210 /* ISO 8601 Week Of Year:
211 If the week (Monday - Sunday) containing
212 January 1 has four or more days in the new
213 year, then it is week 1; otherwise it is
214 week 53 of the previous year and the next
215 week is week one. */
216
217 int week = MON_WEEK(t);
218
219 if (((t->tm_yday + 7 - (t->tm_wday + 1)) % 7) >= 4) {
220 week++;
221 } else if (week == 0) {
222 week = 53;
223 }
224
225 if (!_conv(week, 2, '0'))
226 return(0);
227 continue;
228 }
229 case 'W':
230 if (!_conv(MON_WEEK(t), 2, '0'))
231 return(0);
232 continue;
233 case 'w':
234 if (!_conv(t->tm_wday, 1, '0'))
235 return(0);
236 continue;
237 case 'x':
238 if (!_fmt(_CurrentTimeLocale->d_fmt, t))
239 return(0);
240 continue;
241 case 'X':
242 if (!_fmt(_CurrentTimeLocale->t_fmt, t))
243 return(0);
244 continue;
245 case 'y':
246 if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
247 2, '0'))
248 return(0);
249 continue;
250 case 'Y':
251 if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
252 return(0);
253 continue;
254 case 'Z':
255 if (t->tm_zone && !_add(t->tm_zone))
256 return(0);
257 continue;
258 case '%':
259 /*
260 * X311J/88-090 (4.12.3.5): if conversion char is
261 * undefined, behavior is undefined. Print out the
262 * character itself as printf(3) does.
263 */
264 default:
265 break;
266 }
267 }
268 if (!gsize--)
269 return(0);
270 *pt++ = *format;
271 }
272 return(gsize);
273}
274
275static
276_secs(t)
277 struct tm *t;
278{
279 static char buf[15];
280 register time_t s;
281 register char *p;
282 struct tm tmp;
283
284 /* Make a copy, mktime(3) modifies the tm struct. */
285 tmp = *t;
286 s = mktime(&tmp);
287 for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
288 *p-- = s % 10 + '0';
289 return(_add(++p));
290}
291
292static
293_conv(n, digits, pad)
294 int n, digits;
295 char pad;
296{
297 static char buf[10];
298 register char *p;
299
300 for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
301 *p-- = n % 10 + '0';
302 while (p > buf && digits-- > 0)
303 *p-- = pad;
304 return(_add(++p));
305}
306
307static
308_add(str)
309 register char *str;
310{
311 for (;; ++pt, --gsize) {
312 if (!gsize)
313 return(0);
314 if (!(*pt = *str++))
315 return(1);
316 }
317}
diff --git a/src/lib/libc/string/string.3 b/src/lib/libc/string/string.3
index aaf97e0321..4d47ad444d 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.12 2007/05/31 19:19:32 jmc Exp $
35.\" $Id: string.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
36.\" 31.\"
37.Dd April 19, 1991 32.Dd $Mdocdate: May 31 2007 $
38.Dt STRING 3 33.Dt STRING 3
39.Os BSD 4 34.Os
40.Sh NAME 35.Sh NAME
41.Nm strcat , 36.Nm string
42.Nm strncat ,
43.Nm strchr ,
44.Nm strrchr ,
45.Nm strcmp ,
46.Nm strncmp ,
47.Nm strcasecmp,
48.Nm strncasecmp ,
49.Nm strcpy ,
50.Nm strncpy ,
51.Nm strerror ,
52.Nm strlen ,
53.Nm strpbrk ,
54.Nm strsep,
55.Nm strspn ,
56.Nm strcspn ,
57.Nm strstr ,
58.Nm strtok ,
59.Nm index ,
60.Nm rindex
61.Nd string specific functions 37.Nd string specific functions
62.Sh SYNOPSIS 38.Sh SYNOPSIS
63.Fd #include <string.h> 39.Fd #include <string.h>
64.Ft char * 40.Ft char *
65.Fn strcat "char *s" "const char * append" 41.Fn strcat "char *s" "const char *append"
42.Ft char *
43.Fn strlcat "char *s" "const char *append" "size_t size"
66.Ft char * 44.Ft char *
67.Fn strncat "char *s" "const char *append" "size_t count" 45.Fn strncat "char *s" "const char *append" "size_t count"
68.Ft char * 46.Ft char *
@@ -80,6 +58,8 @@
80.Ft char * 58.Ft char *
81.Fn strcpy "char *dst" "const char *src" 59.Fn strcpy "char *dst" "const char *src"
82.Ft char * 60.Ft char *
61.Fn strlcpy "char *dst" "const char *src" "size_t size"
62.Ft char *
83.Fn strncpy "char *dst" "const char *src" "size_t count" 63.Fn strncpy "char *dst" "const char *src" "size_t count"
84.Ft char * 64.Ft char *
85.Fn strerror "int errno" 65.Fn strerror "int errno"
@@ -103,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
105The string functions 85The string functions
106functions manipulate strings terminated by a 86manipulate strings terminated by a
107null byte. 87NUL byte.
108.Pp 88.Pp
109See the specific manual pages for more information. 89See the specific manual pages for more information.
110For manipulating variable length generic objects as byte 90For manipulating variable length generic objects as byte
111strings (without the null byte check), see 91strings (without the NUL-byte check), see
112.Xr bstring 3 . 92.Xr bstring 3 .
113.Pp 93.Pp
114Except as noted in their specific manual pages, 94Except as noted in their specific manual pages,
115the string functions do not test the destination 95the string functions do not test the destination
116for size limitations. 96for size limitations.
117.Sh SEE ALSO 97.Sh SEE ALSO
98.Xr bstring 3 ,
118.Xr index 3 , 99.Xr index 3 ,
100.Xr rindex 3 ,
101.Xr strcasecmp 3 ,
119.Xr strcat 3 , 102.Xr strcat 3 ,
120.Xr strchr 3 , 103.Xr strchr 3 ,
121.Xr strrchr 3 ,
122.Xr strcmp 3 , 104.Xr strcmp 3 ,
123.Xr strcasecmp 3 ,
124.Xr strcpy 3 , 105.Xr strcpy 3 ,
106.Xr strcspn 3 ,
125.Xr strerror 3 , 107.Xr strerror 3 ,
108.Xr strlcat 3 ,
109.Xr strlcpy 3 ,
126.Xr strlen 3 , 110.Xr strlen 3 ,
127.Xr strpbrk 3 , 111.Xr strpbrk 3 ,
112.Xr strrchr 3 ,
128.Xr strsep 3 , 113.Xr strsep 3 ,
129.Xr strspn 3 , 114.Xr strspn 3 ,
130.Xr strcspn 3 ,
131.Xr strstr 3 , 115.Xr strstr 3 ,
132.Xr strtok 3 , 116.Xr strtok 3
133.Xr rindex 3
134.Xr bstring 3
135.Sh STANDARDS 117.Sh STANDARDS
136The 118The
137.Fn strcat , 119.Fn strcat ,
@@ -145,12 +127,10 @@ The
145.Fn strerror , 127.Fn strerror ,
146.Fn strlen , 128.Fn strlen ,
147.Fn strpbrk , 129.Fn strpbrk ,
148.Fn strsep ,
149.Fn strspn , 130.Fn strspn ,
150.Fn strcspn , 131.Fn strcspn ,
151.Fn strstr , 132.Fn strstr ,
152and 133and
153.Fn strtok 134.Fn strtok
154functions 135functions conform to
155conform to
156.St -ansiC . 136.St -ansiC .
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..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 */
29size_t
30strlcat(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..feda63fae7
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,186 @@
1.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc 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: May 31 2007 $
18.Dt STRLCPY 3
19.Os
20.Sh NAME
21.Nm strlcpy ,
22.Nm strlcat
23.Nd size-bounded string copying and concatenation
24.Sh SYNOPSIS
25.Fd #include <string.h>
26.Ft size_t
27.Fn strlcpy "char *dst" "const char *src" "size_t size"
28.Ft size_t
29.Fn strlcat "char *dst" "const char *src" "size_t size"
30.Sh DESCRIPTION
31The
32.Fn strlcpy
33and
34.Fn strlcat
35functions copy and concatenate strings respectively.
36They are designed
37to be safer, more consistent, and less error prone replacements for
38.Xr strncpy 3
39and
40.Xr strncat 3 .
41Unlike those functions,
42.Fn strlcpy
43and
44.Fn strlcat
45take the full size of the buffer (not just the length) and guarantee to
46NUL-terminate the result (as long as
47.Fa size
48is larger than 0 or, in the case of
49.Fn strlcat ,
50as long as there is at least one byte free in
51.Fa dst ) .
52Note that a byte for the NUL should be included in
53.Fa size .
54Also note that
55.Fn strlcpy
56and
57.Fn strlcat
58only operate on true
59.Dq C
60strings.
61This means that for
62.Fn strlcpy
63.Fa src
64must be NUL-terminated and for
65.Fn strlcat
66both
67.Fa src
68and
69.Fa dst
70must be NUL-terminated.
71.Pp
72The
73.Fn strlcpy
74function copies up to
75.Fa size
76- 1 characters from the NUL-terminated string
77.Fa src
78to
79.Fa dst ,
80NUL-terminating the result.
81.Pp
82The
83.Fn strlcat
84function appends the NUL-terminated string
85.Fa src
86to the end of
87.Fa dst .
88It will append at most
89.Fa size
90- strlen(dst) - 1 bytes, NUL-terminating the result.
91.Sh RETURN VALUES
92The
93.Fn strlcpy
94and
95.Fn strlcat
96functions return the total length of the string they tried to create.
97For
98.Fn strlcpy
99that means the length of
100.Fa src .
101For
102.Fn strlcat
103that means the initial length of
104.Fa dst
105plus
106the length of
107.Fa src .
108While this may seem somewhat confusing, it was done to make
109truncation detection simple.
110.Pp
111Note, however, that if
112.Fn strlcat
113traverses
114.Fa size
115characters without finding a NUL, the length of the string is considered
116to be
117.Fa size
118and the destination string will not be NUL-terminated (since there was
119no space for the NUL).
120This keeps
121.Fn strlcat
122from running off the end of a string.
123In practice this should not happen (as it means that either
124.Fa size
125is incorrect or that
126.Fa dst
127is not a proper
128.Dq C
129string).
130The check exists to prevent potential security problems in incorrect code.
131.Sh EXAMPLES
132The following code fragment illustrates the simple case:
133.Bd -literal -offset indent
134char *s, *p, buf[BUFSIZ];
135
136\&...
137
138(void)strlcpy(buf, s, sizeof(buf));
139(void)strlcat(buf, p, sizeof(buf));
140.Ed
141.Pp
142To detect truncation, perhaps while building a pathname, something
143like the following might be used:
144.Bd -literal -offset indent
145char *dir, *file, pname[MAXPATHLEN];
146
147\&...
148
149if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
150 goto toolong;
151if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
152 goto toolong;
153.Ed
154.Pp
155Since it is known how many characters were copied the first time, things
156can be sped up a bit by using a copy instead of an append:
157.Bd -literal -offset indent
158char *dir, *file, pname[MAXPATHLEN];
159size_t n;
160
161\&...
162
163n = strlcpy(pname, dir, sizeof(pname));
164if (n >= sizeof(pname))
165 goto toolong;
166if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
167 goto toolong;
168.Ed
169.Pp
170However, one may question the validity of such optimizations, as they
171defeat the whole purpose of
172.Fn strlcpy
173and
174.Fn strlcat .
175As a matter of fact, the first version of this manual page got it wrong.
176.Sh SEE ALSO
177.Xr snprintf 3 ,
178.Xr strncat 3 ,
179.Xr strncpy 3
180.Sh HISTORY
181The
182.Fn strlcpy
183and
184.Fn strlcat
185functions first appeared in
186.Ox 2.4 .
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 */
27size_t
28strlcpy(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..f8a4efe9d2 100644
--- a/src/lib/libc/string/strlen.3
+++ b/src/lib/libc/string/strlen.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,15 +29,14 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strlen.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strlen.3,v 1.6 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strlen.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRLEN 3 35.Dt STRLEN 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strlen 38.Nm strlen
44.Nd find length of string 39.Nd find length of a string
45.Sh SYNOPSIS 40.Sh SYNOPSIS
46.Fd #include <string.h> 41.Fd #include <string.h>
47.Ft size_t 42.Ft size_t
@@ -49,23 +44,18 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strlen 46.Fn strlen
52function 47function computes the length of the string
53computes the length of the string
54.Fa s . 48.Fa s .
55.Sh RETURN VALUES 49.Sh RETURN VALUES
56The 50The
57.Fn strlen 51.Fn strlen
58function 52function returns the number of characters that precede the terminating
59returns 53.Tn NUL
60the number of characters that precede the
61terminating
62.Dv NUL
63character. 54character.
64.Sh SEE ALSO 55.Sh SEE ALSO
65.Xr string 3 56.Xr string 3
66.Sh STANDARDS 57.Sh STANDARDS
67The 58The
68.Fn strlen 59.Fn strlen
69function 60function conforms to
70conforms to
71.St -ansiC . 61.St -ansiC .
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c
index d23aadafc0..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";*/
36static char *rcsid = "$Id: strlen.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
40 37
41size_t 38size_t
42strlen(str) 39strlen(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..ebeafcaf6e 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.14 2007/05/31 19:19:32 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
@@ -9,11 +11,7 @@
9.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software 14.\" 3. Neither the name of the University nor the names of its contributors
13.\" must display the following acknowledgement:
14.\" This product includes software developed by the University of
15.\" California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software 15.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 16.\" without specific prior written permission.
19.\" 17.\"
@@ -29,10 +27,9 @@
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
31.\" 29.\"
32.\" from: @(#)strmode.3 5.4 (Berkeley) 7/31/91 30.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
33.\" $Id: strmode.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
34.\" 31.\"
35.Dd July 31, 1991 32.Dd $Mdocdate: May 31 2007 $
36.Dt STRMODE 3 33.Dt STRMODE 3
37.Os 34.Os
38.Sh NAME 35.Sh NAME
@@ -45,15 +42,13 @@
45.Sh DESCRIPTION 42.Sh DESCRIPTION
46The 43The
47.Fn strmode 44.Fn strmode
48function 45function converts a file
49converts a file
50.Fa mode 46.Fa mode
51(the type and permission information associated with an inode, see 47(the type and permission information associated with an inode, see
52.Xr stat 2 ) 48.Xr stat 2 )
53into a symbolic string which is stored in the location referenced by 49into a symbolic string which is stored in the location referenced by
54.Fa bp . 50.Fa bp .
55This stored string is eleven characters in length plus a trailing 51This stored string is eleven characters in length plus a trailing NUL byte.
56.Dv NULL .
57.Pp 52.Pp
58The first character is the inode type, and will be one of the following: 53The first character is the inode type, and will be one of the following:
59.Pp 54.Pp
@@ -69,10 +64,10 @@ directory
69.It l 64.It l
70symbolic link 65symbolic link
71.It p 66.It p
72fifo 67FIFO
73.It s 68.It s
74socket 69socket
75.It ? 70.It \&?
76unknown inode type 71unknown 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
80characters each. 75characters each.
81The first three characters are the permissions for the owner of the 76The first three characters are the permissions for the owner of the
82file, the second three for the group the file belongs to, and the 77file, the second three for the group the file belongs to, and the
83third for the ``other'', or default, set of users. 78third for the
79.Dq other ,
80or default, set of users.
84.Pp 81.Pp
85Permission checking is done as specifically as possible. 82Permission checking is done as specifically as possible.
86If read permission is denied to the owner of a file in the first set 83If read permission is denied to the owner of a file in the first set
87of permissions, the owner of the file will not be able to read the file. 84of permissions, the owner of the file will not be able to read the file.
88This is true even if the owner is in the file's group and the group 85This is true even if the owner is in the file's group and the group
89permissions allow reading or the ``other'' permissions allow reading. 86permissions allow reading or the
87.Dq other
88permissions allow reading.
90.Pp 89.Pp
91If the first character of the three character set is an ``r'', the file is 90If the first character of the three character set is an
92readable for that set of users; if a dash ``\-'', it is not readable. 91.Sq r ,
92the file is readable for that set of users; if a dash
93.Pq Ql - ,
94it is not readable.
93.Pp 95.Pp
94If the second character of the three character set is a ``w'', the file is 96If the second character of the three character set is a
95writable for that set of users; if a dash ``\-'', it is not writable. 97.Sq w ,
98the file is writable for that set of users; if a dash
99.Pq Ql - ,
100it is not writable.
96.Pp 101.Pp
97The third character is the first of the following characters that apply: 102The 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
100If the character is part of the owner permissions and the file is not 105If the character is part of the owner permissions and the file is not
101executable or the directory is not searchable, by the owner, and the 106executable or the directory is not searchable by the owner, and the
102set-user-id bit is set. 107set-user-ID bit is set.
103.It S 108.It S
104If the character is part of the group permissions and the file is not 109If the character is part of the group permissions and the file is not
105executable or the directory is not searchable, by the group, and the 110executable or the directory is not searchable by the group, and the
106set-group-id bit is set. 111set-group-ID bit is set.
107.It T 112.It T
108If the character is part of the other permissions and the file is not 113If the character is part of the other permissions and the file is not
109executable or the directory is not searchable, by others, and the ``sticky'' 114executable or the directory is not searchable by others, and the
115.Dq sticky
110.Pq Dv S_ISVTX 116.Pq Dv S_ISVTX
111bit is set. 117bit is set.
112.It s 118.It s
113If the character is part of the owner permissions and the file is 119If the character is part of the owner permissions and the file is
114executable or the directory searchable, by the owner, and the set-user-id 120executable or the directory searchable by the owner, and the set-user-ID
115bit is set. 121bit is set.
116.It s 122.It s
117If the character is part of the group permissions and the file is 123If the character is part of the group permissions and the file is
118executable or the directory searchable, by the group, and the set-group-id 124executable or the directory searchable by the group, and the set-group-ID
119bit is set. 125bit is set.
120.It t 126.It t
121If the character is part of the other permissions and the file is 127If the character is part of the other permissions and the file is
122executable or the directory searchable, by others, and the ``sticky'' 128executable or the directory searchable by others, and the
129.Dq sticky
123.Pq Dv S_ISVTX 130.Pq Dv S_ISVTX
124bit is set. 131bit is set.
125.It x 132.It x
@@ -128,14 +135,15 @@ The file is executable or the directory is searchable.
128None of the above apply. 135None of the above apply.
129.El 136.El
130.Pp 137.Pp
131The last character is a plus sign ``+'' if any there are any alternate 138The last character is a plus sign
139.Pq Ql +
140if there are any alternate
132or additional access control methods associated with the inode, otherwise 141or additional access control methods associated with the inode, otherwise
133it will be a space. 142it will be a space.
134.Sh RETURN VALUES 143.Sh RETURN VALUES
135The 144The
136.Fn strmode 145.Fn strmode
137function 146function always returns 0.
138always 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
146The 154The
147.Fn strmode 155.Fn strmode
148function 156function first appeared in
149.Ud . 157.Bx 4.4 .
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";*/
36static char *rcsid = "$Id: strmode.c,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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
43void 37void
44strmode(mode, p) 38strmode(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.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";*/
39static char *rcsid = "$Id: strncat.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
48char * 40char *
49strncat(dst, src, n) 41strncat(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";*/
36static char *rcsid = "$Id: strncmp.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
40 37
41int 38int
42strncmp(s1, s2, n) 39strncmp(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.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";*/
39static char *rcsid = "$Id: strncpy.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
48char * 45char *
49strncpy(dst, src, n) 46strncpy(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/strpbrk.3 b/src/lib/libc/string/strpbrk.3
index 8578546c05..9d6c676c8d 100644
--- a/src/lib/libc/string/strpbrk.3
+++ b/src/lib/libc/string/strpbrk.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)strpbrk.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strpbrk.3,v 1.8 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strpbrk.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRPBRK 3 35.Dt STRPBRK 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -49,8 +44,7 @@
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Fn strpbrk 46.Fn strpbrk
52function 47function locates in the NUL-terminated string
53locates in the null-terminated string
54.Fa s 48.Fa s
55the first occurrence of any character in the string 49the first occurrence of any character in the string
56.Fa charset 50.Fa charset
@@ -58,13 +52,12 @@ and returns a pointer to this character.
58If no characters from 52If no characters from
59.Fa charset 53.Fa charset
60occur anywhere in 54occur anywhere in
61.Fa s 55.Fa s ,
62.Fn strpbrk 56.Fn strpbrk
63returns NULL. 57returns
58.Dv NULL .
64.Sh SEE ALSO 59.Sh SEE ALSO
65.Xr index 3 ,
66.Xr memchr 3 , 60.Xr memchr 3 ,
67.Xr rindex 3 ,
68.Xr strchr 3 , 61.Xr strchr 3 ,
69.Xr strcspn 3 , 62.Xr strcspn 3 ,
70.Xr strrchr 3 , 63.Xr strrchr 3 ,
@@ -75,6 +68,5 @@ returns NULL.
75.Sh STANDARDS 68.Sh STANDARDS
76The 69The
77.Fn strpbrk 70.Fn strpbrk
78function 71function conforms to
79conforms to
80.St -ansiC . 72.St -ansiC .
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c
index f1d542a525..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";*/
36static char *rcsid = "$Id: strpbrk.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 */
44char * 36char *
45strpbrk(s1, s2) 37strpbrk(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..0d1f4be971 100644
--- a/src/lib/libc/string/strrchr.3
+++ b/src/lib/libc/string/strrchr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,28 +29,31 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strrchr.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strrchr.3,v 1.8 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strrchr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRRCHR 3 35.Dt STRRCHR 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strrchr 38.Nm strrchr ,
44.Nd locate character in string 39.Nm rindex
40.Nd locate last occurrence of a character in a string
45.Sh SYNOPSIS 41.Sh SYNOPSIS
46.Fd #include <string.h> 42.Fd #include <string.h>
47.Ft char * 43.Ft char *
48.Fn strrchr "const char *s" "int c" 44.Fn strrchr "const char *s" "int c"
45.Ft char *
46.Fn rindex "const char *s" "int c"
49.Sh DESCRIPTION 47.Sh DESCRIPTION
50The 48The
51.Fn strrchr 49.Fn strrchr
52function 50function locates the last occurrence of the character
53locates the last occurrence of
54.Fa c 51.Fa c
55(converted to a char)
56in the string 52in the string
57.Fa s . 53.Fa s .
54The terminating
55.Tn NUL
56character is considered part of the string.
58If 57If
59.Fa c 58.Fa c
60is 59is
@@ -62,20 +61,31 @@ is
62.Fn strrchr 61.Fn strrchr
63locates the terminating 62locates the terminating
64.Ql \e0 . 63.Ql \e0 .
64.Pp
65The
66.Fn rindex
67function is an old synonym for
68.Fn strrchr .
65.Sh RETURN VALUES 69.Sh RETURN VALUES
66The 70The
67.Fn strrchr 71.Fn strrchr
68function 72function returns a pointer to the located character or
69returns a pointer to the character, 73.Dv NULL
70or a null 74if the character does not appear in the string.
71pointer if 75.Sh EXAMPLES
72.Fa c 76After the following call to
73does not occur anywhere in 77.Fn strrchr ,
74.Fa s . 78.Va p
79will point to the string
80.Qq obar :
81.Bd -literal -offset indent
82char *p;
83char *s = "foobar";
84
85p = strrchr(s, 'o');
86.Ed
75.Sh SEE ALSO 87.Sh SEE ALSO
76.Xr index 3 ,
77.Xr memchr 3 , 88.Xr memchr 3 ,
78.Xr rindex 3 ,
79.Xr strchr 3 , 89.Xr strchr 3 ,
80.Xr strcspn 3 , 90.Xr strcspn 3 ,
81.Xr strpbrk 3 , 91.Xr strpbrk 3 ,
@@ -86,6 +96,9 @@ does not occur anywhere in
86.Sh STANDARDS 96.Sh STANDARDS
87The 97The
88.Fn strrchr 98.Fn strrchr
89function 99function conforms to
90conforms to
91.St -ansiC . 100.St -ansiC .
101.Pp
102The
103.Fn rindex
104function is deprecated and shouldn't be used in new code.
diff --git a/src/lib/libc/string/strsep.3 b/src/lib/libc/string/strsep.3
index 21aa7376f2..cceeda7577 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.12 2007/05/31 19:19:32 jmc Exp $
2.\" All rights reserved. 2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
3.\" 5.\"
4.\" This code is derived from software contributed to Berkeley by 6.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek. 7.\" Chris Torek.
8.\"
6.\" Redistribution and use in source and binary forms, with or without 9.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 10.\" modification, are permitted provided that the following conditions
8.\" are met: 11.\" are met:
@@ -11,11 +14,7 @@
11.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 15.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 16.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software 17.\" 3. Neither the name of the University nor the names of its contributors
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software 18.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission. 19.\" without specific prior written permission.
21.\" 20.\"
@@ -31,10 +30,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 31.\" SUCH DAMAGE.
33.\" 32.\"
34.\" from: @(#)strsep.3 5.3 (Berkeley) 4/19/91 33.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
35.\" $Id: strsep.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
36.\" 34.\"
37.Dd April 19, 1991 35.Dd $Mdocdate: May 31 2007 $
38.Dt STRSEP 3 36.Dt STRSEP 3
39.Os 37.Os
40.Sh NAME 38.Sh NAME
@@ -43,27 +41,37 @@
43.Sh SYNOPSIS 41.Sh SYNOPSIS
44.Fd #include <string.h> 42.Fd #include <string.h>
45.Ft char * 43.Ft char *
46.Fn strsep "char **stringp" "char *delim" 44.Fn strsep "char **stringp" "const char *delim"
47.Sh DESCRIPTION 45.Sh DESCRIPTION
48The 46The
49.Fn strsep 47.Fn strsep
50locates in the null-terminated string at 48function locates, in the string referenced by
51.Fa *stringp
52the first occurrence of any character in
53.Fa delim
54and replaces this with a
55.Ql \e0 ,
56records the location of the immediate following character in
57.Fa *stringp , 49.Fa *stringp ,
58then returns the original value of 50the first occurrence of any character in the string
51.Fa delim
52(or the terminating
53.Ql \e0
54character) and replaces it with a
55.Ql \e0 .
56The location of the next character after the delimiter character
57(or
58.Dv NULL ,
59if the end of the string was reached) is stored in
59.Fa *stringp . 60.Fa *stringp .
60If no delimiter characters are found, 61The original value of
61.Fn strsep
62sets
63.Fa *stringp 62.Fa *stringp
63is returned.
64.Pp
65An
66.Dq empty
67field, i.e., one caused by two adjacent delimiter characters,
68can be detected by comparing the location referenced by the pointer returned
69by
70.Fn strsep
64to 71to
65.Dv NULL ; 72.Ql \e0 .
66if 73.Pp
74If
67.Fa *stringp 75.Fa *stringp
68is initially 76is initially
69.Dv NULL , 77.Dv NULL ,
@@ -73,20 +81,32 @@ returns
73.Sh EXAMPLES 81.Sh EXAMPLES
74The following uses 82The following uses
75.Fn strsep 83.Fn strsep
76to parse strings containing runs of white space, 84to parse a string, containing tokens delimited by whitespace, into an
77making up an argument vector: 85argument vector:
78.Bd -literal -offset indent 86.Bd -literal -offset indent
79char inputstring[100]; 87char **ap, *argv[10], *inputstring;
80char **argv[51], **ap = argv, *p, *val; 88
81/* set up inputstring */ 89for (ap = argv; ap < &argv[9] &&
82for (p = inputstring; p != NULL; ) { 90 (*ap = strsep(&inputstring, " \et")) != NULL;) {
83 while ((val = strsep(&p, " \et")) != NULL && *val == '\e0'); 91 if (**ap != '\e0')
84 *ap++ = val; 92 ap++;
85} 93}
86*ap = 0; 94*ap = NULL;
87.Ed 95.Ed
88.Sh HISTORY 96.Sh HISTORY
89The 97The
90.Fn strsep 98.Fn strsep
91function is 99function is intended as a replacement for the
92.Ud . 100.Fn strtok
101function.
102While the
103.Fn strtok
104function should be preferred for portability reasons (it conforms to
105.St -ansiC )
106it is unable to handle empty fields, i.e., detect fields delimited by
107two adjacent delimiter characters, or to be used for more than a single
108string at a time.
109The
110.Fn strsep
111function first appeared in
112.Bx 4.4 .
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c
index 69be7fe046..bcca681e03 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.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,15 +29,11 @@
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";*/
36static 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>
33#include <stdio.h>
40 34
41/* 35/*
42 * Get next token from string *stringp, where tokens are nonempty 36 * Get next token from string *stringp, where tokens are possibly-empty
43 * strings separated by characters from delim. 37 * strings separated by characters from delim.
44 * 38 *
45 * Writes NULs into the string at *stringp to end tokens. 39 * Writes NULs into the string at *stringp to end tokens.
@@ -47,16 +41,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 41 * 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). 42 * be further tokens), or is NULL (if there are definitely no more tokens).
49 * 43 *
50 * If *stringp is NULL, strtoken returns NULL. 44 * If *stringp is NULL, strsep returns NULL.
51 */ 45 */
52char * 46char *
53strsep(stringp, delim) 47strsep(char **stringp, const char *delim)
54 register char **stringp;
55 register const char *delim;
56{ 48{
57 register char *s; 49 char *s;
58 register const char *spanp; 50 const char *spanp;
59 register int c, sc; 51 int c, sc;
60 char *tok; 52 char *tok;
61 53
62 if ((s = *stringp) == NULL) 54 if ((s = *stringp) == NULL)
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3
index 3287fef53e..839402dcb1 100644
--- a/src/lib/libc/string/strsignal.3
+++ b/src/lib/libc/string/strsignal.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,12 +29,11 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strerror.3 6.9 (Berkeley) 6/29/91 32.\" $OpenBSD: strsignal.3,v 1.5 2007/05/31 19:19:32 jmc 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: May 31 2007 $
40.Dt STRSIGNAL 3 35.Dt STRSIGNAL 3
41.Os BSD 4 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strsignal 38.Nm strsignal
44.Nd get signal description string 39.Nd get signal description string
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c
index ec4a267edf..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";*/
36static char *rcsid = "$Id: strsignal.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 30#include <string.h>
40#include <limits.h> 31#include <limits.h>
41 32
42extern char *__strsignal __P((int, char *)); 33extern char *__strsignal(int, char *);
43 34
44char * 35char *
45strsignal(sig) 36strsignal(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..f902ca35d2 100644
--- a/src/lib/libc/string/strspn.3
+++ b/src/lib/libc/string/strspn.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,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: @(#)strspn.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strspn.3,v 1.9 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strspn.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRSPN 3 35.Dt STRSPN 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -48,9 +43,8 @@
48.Fn strspn "const char *s" "const char *charset" 43.Fn strspn "const char *s" "const char *charset"
49.Sh DESCRIPTION 44.Sh DESCRIPTION
50The 45The
51.Xr strcspn 46.Fn strspn
52function 47function spans the initial part of the NUL-terminated string
53spans the initial part of the null-terminated string
54.Fa s 48.Fa s
55as long as the characters from 49as long as the characters from
56.Fa s 50.Fa s
@@ -59,12 +53,23 @@ occur in string
59.Sh RETURN VALUES 53.Sh RETURN VALUES
60The 54The
61.Fn strspn 55.Fn strspn
62function 56function returns the number of characters spanned.
63returns the number of characters spanned. 57.Sh EXAMPLES
58The following call to
59.Fn strspn
60will return 3, since the first three characters of string
61.Fa s
62are part of string
63.Fa charset :
64.Bd -literal -offset indent
65char *s = "foobar";
66char *charset = "of";
67size_t span;
68
69span = strspn(s, charset);
70.Ed
64.Sh SEE ALSO 71.Sh SEE ALSO
65.Xr index 3 ,
66.Xr memchr 3 , 72.Xr memchr 3 ,
67.Xr rindex 3 ,
68.Xr strchr 3 , 73.Xr strchr 3 ,
69.Xr strcspn 3 , 74.Xr strcspn 3 ,
70.Xr strpbrk 3 , 75.Xr strpbrk 3 ,
@@ -75,6 +80,5 @@ returns the number of characters spanned.
75.Sh STANDARDS 80.Sh STANDARDS
76The 81The
77.Fn strspn 82.Fn strspn
78function 83function conforms to
79conforms to
80.St -ansiC . 84.St -ansiC .
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c
index 6224b25c2a..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";*/
36static char *rcsid = "$Id: strspn.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
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 */
44size_t 36size_t
45strspn(s1, s2) 37strspn(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..38bd207727 100644
--- a/src/lib/libc/string/strstr.3
+++ b/src/lib/libc/string/strstr.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,47 +29,50 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strstr.3 5.3 (Berkeley) 6/29/91 32.\" $OpenBSD: strstr.3,v 1.10 2007/09/19 16:06:45 jmc Exp $
37.\" $Id: strstr.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: September 19 2007 $
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.Fd #include <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
50The 47The
51.Fn strstr 48.Fn strstr
52function 49function locates the first occurrence of the NUL-terminated string
53locates the first occurrence of the null-terminated string
54.Fa little 50.Fa little
55in the null-terminated string 51in the NUL-terminated string
56.Fa big . 52.Fa big .
53.Pp
54The
55.Fn strcasestr
56function is similar to
57.Fn strstr
58but ignores the case of both strings.
59.Pp
57If 60If
58.Fa little 61.Fa little
59is the empty string, 62is an empty string,
60.Fn strstr 63.Fa big
61returns 64is returned;
62.Fa big ;
63if 65if
64.Fa little 66.Fa little
65occurs nowhere in 67occurs nowhere in
66.Fa big , 68.Fa big ,
67.Fn strstr 69.Dv NULL
68returns NULL; 70is returned;
69otherwise 71otherwise a pointer to the first character of the first occurrence of
70.Fn strstr 72.Fa little
71returns a pointer to the first character of the first occurrence of 73is 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 ,
@@ -84,6 +83,10 @@ returns a pointer to the first character of the first occurrence of
84.Sh STANDARDS 83.Sh STANDARDS
85The 84The
86.Fn strstr 85.Fn strstr
87function 86function conforms to
88conforms to
89.St -ansiC . 87.St -ansiC .
88.Sh HISTORY
89The
90.Fn strcasestr
91function first appeared in
92.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";*/
39static char *rcsid = "$Id: strstr.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
47char * 39char *
48strstr(s, find) 40strstr(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..ed7d5158ed 100644
--- a/src/lib/libc/string/strtok.3
+++ b/src/lib/libc/string/strtok.3
@@ -13,11 +13,7 @@
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. All advertising materials mentioning features or use of this software 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" must display the following acknowledgement:
18.\" This product includes software developed by the University of
19.\" California, Berkeley and its contributors.
20.\" 4. Neither the name of the University nor the names of its contributors
21.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
22.\" without specific prior written permission. 18.\" without specific prior written permission.
23.\" 19.\"
@@ -33,29 +29,30 @@
33.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
35.\" 31.\"
36.\" from: @(#)strtok.3 5.8 (Berkeley) 6/29/91 32.\" $OpenBSD: strtok.3,v 1.19 2007/05/31 19:19:32 jmc Exp $
37.\" $Id: strtok.3,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $
38.\" 33.\"
39.Dd June 29, 1991 34.Dd $Mdocdate: May 31 2007 $
40.Dt STRTOK 3 35.Dt STRTOK 3
41.Os BSD 3 36.Os
42.Sh NAME 37.Sh NAME
43.Nm strtok , 38.Nm strtok ,
44.Nm strsep 39.Nm strtok_r
45.Nd string token operations 40.Nd string token operations
46.Sh SYNOPSIS 41.Sh SYNOPSIS
47.Fd #include <string.h> 42.Fd #include <string.h>
48.Ft char * 43.Ft char *
49.Fn strtok "char *str" "const char *sep" 44.Fn strtok "char *str" "const char *sep"
45.Ft char *
46.Fn strtok_r "char *str" "const char *sep" "char **last"
50.Sh DESCRIPTION 47.Sh DESCRIPTION
51.Bf -symbolic 48.Bf -symbolic
52This interface is obsoleted by strsep(3). 49This interface is obsoleted by
50.Xr strsep 3 .
53.Ef 51.Ef
54.Pp 52.Pp
55The 53The
56.Fn strtok 54.Fn strtok
57function 55function is used to isolate sequential tokens in a NUL-terminated string,
58is used to isolate sequential tokens in a null-terminated string,
59.Fa str . 56.Fa str .
60These tokens are separated in the string by at least one of the 57These tokens are separated in the string by at least one of the
61characters in 58characters in
@@ -71,17 +68,65 @@ The separator string,
71must be supplied each time, and may change between calls. 68must be supplied each time, and may change between calls.
72.Pp 69.Pp
73The 70The
71.Fn strtok_r
72function is a version of
74.Fn strtok 73.Fn strtok
75function 74that takes an explicit context argument and is reentrant.
76returns a pointer to the beginning of each subsequent token in the string, 75.Pp
77after replacing the separator character itself with a 76The
78.Dv NUL 77.Fn strtok
78and
79.Fn strtok_r
80functions return a pointer to the beginning of each subsequent token
81in the string, after replacing the separator character itself with an
82.Tn ASCII NUL
79character. 83character.
80When no more tokens remain, a null pointer is returned. 84When no more tokens remain, a null pointer is returned.
85.Pp
86Since
87.Fn strtok
88and
89.Fn strtok_r
90modify the string,
91.Fa str
92should not point to an area in the initialized data segment.
93.Sh EXAMPLES
94The following will construct an array of pointers to each individual word in
95the string
96.Va s :
97.Bd -literal -offset indent
98#define MAXTOKENS 128
99
100char s[512], *p, *tokens[MAXTOKENS];
101char *last;
102int i = 0;
103
104snprintf(s, sizeof(s), "cat dog horse cow");
105
106for ((p = strtok_r(s, " ", &last)); p;
107 (p = strtok_r(NULL, " ", &last))) {
108 if (i < MAXTOKENS - 1)
109 tokens[i++] = p;
110}
111tokens[i] = NULL;
112.Ed
113.Pp
114That is,
115.Li tokens[0]
116will point to
117.Qq cat ,
118.Li tokens[1]
119will point to
120.Qq dog ,
121.Li tokens[2]
122will point to
123.Qq horse ,
124and
125.Li tokens[3]
126will point to
127.Qq cow .
81.Sh SEE ALSO 128.Sh SEE ALSO
82.Xr index 3 ,
83.Xr memchr 3 , 129.Xr memchr 3 ,
84.Xr rindex 3 ,
85.Xr strchr 3 , 130.Xr strchr 3 ,
86.Xr strcspn 3 , 131.Xr strcspn 3 ,
87.Xr strpbrk 3 , 132.Xr strpbrk 3 ,
@@ -92,21 +137,16 @@ When no more tokens remain, a null pointer is returned.
92.Sh STANDARDS 137.Sh STANDARDS
93The 138The
94.Fn strtok 139.Fn strtok
95function 140function conforms to
96conforms to
97.St -ansiC . 141.St -ansiC .
98.Sh BUGS 142.Sh BUGS
99There is no way to get tokens from multiple strings simultaneously.
100.Pp
101The System V 143The System V
102.Fn strtok , 144.Fn strtok ,
103if handed a string containing only delimiter characters, 145if handed a string containing only delimiter characters,
104will not alter the next starting point, so that a call to 146will not alter the next starting point, so that a call to
105.Fn strtok 147.Fn strtok
106with a different (or empty) delimiter string 148with a different (or empty) delimiter string
107may return a 149may return a non-null value.
108.Pf non- Dv NULL
109value.
110Since this implementation always alters the next starting point, 150Since this implementation always alters the next starting point,
111such a sequence of calls would always return 151such a sequence of calls would always return
112.Dv NULL . 152.Dv NULL .
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c
index 9f712579bf..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";*/
36static char *rcsid = "$Id: strtok.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <string.h> 30#include <string.h>
40 31
41char * 32char *
42strtok(s, delim) 33strtok(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
40char *
41strtok_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..73ce135191 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,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: @(#)strxfrm.3 5.4 (Berkeley) 6/29/91 32.\" $OpenBSD: strxfrm.3,v 1.8 2007/05/31 19:19:32 jmc 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: May 31 2007 $
40.Dt STRXFRM 3 35.Dt STRXFRM 3
41.Os 36.Os
42.Sh NAME 37.Sh NAME
@@ -47,23 +42,33 @@
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
50The 45The idea of
51.Fn strxfrm 46.Fn strxfrm
52function 47is to
53does something horrible (see 48.Dq un-localize
54.Tn ANSI 49a string: the function transforms
55standard). 50.Ar src ,
56In this implementation it just copies. 51storing the result in
52.Ar dst ,
53such that
54.Xr strcmp 3
55on transformed strings returns what
56.Xr strcoll 3
57on 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
65The 66The
66.Fn strxfrm 67.Fn strxfrm
67function 68function conforms to
68conforms to
69.St -ansiC . 69.St -ansiC .
70.Sh BUGS
71Since locales are not fully implemented on
72.Ox ,
73.Fn strxfrm
74just 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";*/
39static char *rcsid = "$Id: strxfrm.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
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 */
49size_t 41size_t
50strxfrm(dst, src, n) 42strxfrm(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..56def1ec88 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.6 2007/05/31 19:19:32 jmc 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: May 31 2007 $
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.Fd #include <unistd.h>
43.Ft void 38.Ft void
44.Fn swab "const void *src" "void *dst" "size_t len" 39.Fn swab "const void *src" "void *dst" "size_t len"
45.Sh DESCRIPTION 40.Sh DESCRIPTION
@@ -55,7 +50,7 @@ swapping adjacent bytes.
55.Pp 50.Pp
56The argument 51The argument
57.Fa len 52.Fa len
58must be even number. 53must be an even number.
59.Sh SEE ALSO 54.Sh SEE ALSO
60.Xr bzero 3 , 55.Xr bzero 3 ,
61.Xr memset 3 56.Xr memset 3
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c
index f33fc53bd6..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";*/
39static char *rcsid = "$Id: swab.c,v 1.1.1.1 1995/10/18 08:42:23 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */
41
42#include <string.h>
43 35
44void 36void
45swab(from, to, len) 37swab(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/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
39wchar_t *
40wcscat(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.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
34wchar_t *
35wcschr(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.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 */
42int
43wcscmp(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.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
39wchar_t *
40wcscpy(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.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
34size_t
35wcscspn(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
51done:
52 return (p - s);
53}
diff --git a/src/lib/libc/string/wcslcat.c b/src/lib/libc/string/wcslcat.c
new file mode 100644
index 0000000000..bcd52d1f3c
--- /dev/null
+++ b/src/lib/libc/string/wcslcat.c
@@ -0,0 +1,68 @@
1/* $OpenBSD: wcslcat.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcslcat.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */
3/* from OpenBSD: strlcat.c,v 1.3 2000/11/24 11:10:02 itojun Exp */
4
5/*
6 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
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 * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <wchar.h>
34
35/*
36 * Appends src to string dst of size siz (unlike wcsncat, siz is the
37 * full size of dst, not space left). At most siz-1 characters
38 * will be copied. Always NUL terminates (unless siz == 0).
39 * Returns wcslen(initial dst) + wcslen(src); if retval >= siz,
40 * truncation occurred.
41 */
42size_t
43wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
44{
45 wchar_t *d = dst;
46 const wchar_t *s = src;
47 size_t n = siz;
48 size_t dlen;
49
50 /* Find the end of dst and adjust bytes left but don't go past end */
51 while (*d != '\0' && n-- != 0)
52 d++;
53 dlen = d - dst;
54 n = siz - dlen;
55
56 if (n == 0)
57 return(dlen + wcslen(s));
58 while (*s != '\0') {
59 if (n != 1) {
60 *d++ = *s;
61 n--;
62 }
63 s++;
64 }
65 *d = '\0';
66
67 return(dlen + (s - src)); /* count does not include NUL */
68}
diff --git a/src/lib/libc/string/wcslcpy.c b/src/lib/libc/string/wcslcpy.c
new file mode 100644
index 0000000000..85f51df35f
--- /dev/null
+++ b/src/lib/libc/string/wcslcpy.c
@@ -0,0 +1,64 @@
1/* $OpenBSD: wcslcpy.c,v 1.4 2006/05/05 15:27:38 millert Exp $ */
2/* $NetBSD: wcslcpy.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */
3/* from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp */
4
5/*
6 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
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 * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <wchar.h>
34
35/*
36 * Copy src to string dst of size siz. At most siz-1 characters
37 * will be copied. Always NUL terminates (unless siz == 0).
38 * Returns wcslen(src); if retval >= siz, truncation occurred.
39 */
40size_t
41wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
42{
43 wchar_t *d = dst;
44 const wchar_t *s = src;
45 size_t n = siz;
46
47 /* Copy as many bytes as will fit */
48 if (n != 0) {
49 while (--n != 0) {
50 if ((*d++ = *s++) == '\0')
51 break;
52 }
53 }
54
55 /* Not enough room in dst, add NUL and traverse rest of src */
56 if (n == 0) {
57 if (siz != 0)
58 *d = '\0'; /* NUL-terminate dst */
59 while (*s++)
60 ;
61 }
62
63 return(s - src - 1); /* count does not include NUL */
64}
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
34size_t
35wcslen(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
34wchar_t *
35wcsncat(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
36int
37wcsncmp(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
34wchar_t *
35wcsncpy(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.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
34wchar_t *
35wcspbrk(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.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
34wchar_t *
35wcsrchr(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.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
34size_t
35wcsspn(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
53done:
54 return (p - s);
55}
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
34wchar_t *
35#ifdef WCSWCS
36wcswcs(const wchar_t *big, const wchar_t *little)
37#else
38wcsstr(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..fe65f120e3
--- /dev/null
+++ b/src/lib/libc/string/wcstok.3
@@ -0,0 +1,136 @@
1.\" $OpenBSD: wcstok.3,v 1.5 2007/05/31 19:19:32 jmc 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: May 31 2007 $
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
68The
69.Fn wcstok
70function
71is used to isolate sequential tokens in a NUL-terminated wide character
72string,
73.Fa str .
74These tokens are separated in the string by at least one of the
75characters in
76.Fa sep .
77The first time that
78.Fn wcstok
79is called,
80.Fa str
81should be specified; subsequent calls, wishing to obtain further tokens
82from the same string, should pass a null pointer instead.
83The separator string,
84.Fa sep ,
85must be supplied each time, and may change between calls.
86The context pointer
87.Fa last
88must be provided on each call.
89.Pp
90The
91.Fn wcstok
92function is the wide character counterpart of the
93.Fn strtok_r
94function.
95.Sh RETURN VALUES
96The
97.Fn wcstok
98function
99returns a pointer to the beginning of each subsequent token in the string,
100after replacing the token itself with a NUL wide character (L'\e0').
101When no more tokens remain, a null pointer is returned.
102.Sh EXAMPLES
103The following code fragment splits a wide character string on
104.Tn ASCII
105space, tab, and newline characters and writes the tokens to
106standard output:
107.Bd -literal -offset indent
108const wchar_t *seps = L" \et\en";
109wchar_t *last, *tok, text[] = L" \enone\ettwo\et\etthree \en";
110
111for (tok = wcstok(text, seps, &last); tok != NULL;
112 tok = wcstok(NULL, seps, &last))
113 wprintf(L"%ls\en", tok);
114.Ed
115.Sh SEE ALSO
116.Xr strtok 3 ,
117.Xr wcschr 3 ,
118.Xr wcscspn 3 ,
119.Xr wcspbrk 3 ,
120.Xr wcsrchr 3 ,
121.Xr wcsspn 3
122.Sh STANDARDS
123The
124.Fn wcstok
125function
126conforms to
127.St -isoC-99 .
128.Sh HISTORY
129Some early implementations of
130.Fn wcstok
131omit the
132context pointer argument,
133.Fa last ,
134and maintain state across calls in a static variable like
135.Fn strtok
136does.
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
47wchar_t *
48wcstok(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 */
61cont:
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.c b/src/lib/libc/string/wcswidth.c
new file mode 100644
index 0000000000..cd240897b5
--- /dev/null
+++ b/src/lib/libc/string/wcswidth.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: wcswidth.c,v 1.3 2005/08/08 08:05:37 espie 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
34int
35wcswidth(const wchar_t *s, size_t n)
36{
37 int w;
38
39 w = 0;
40 while (n && *s) {
41 w += wcwidth(*s);
42 s++;
43 n--;
44 }
45
46 return w;
47}
diff --git a/src/lib/libc/string/wmemchr.3 b/src/lib/libc/string/wmemchr.3
new file mode 100644
index 0000000000..395488829d
--- /dev/null
+++ b/src/lib/libc/string/wmemchr.3
@@ -0,0 +1,141 @@
1.\" $OpenBSD: wmemchr.3,v 1.3 2007/05/31 19:19:32 jmc Exp $
2.\"
3.\" $NetBSD: wmemchr.3,v 1.9 2003/09/08 17:54:33 wiz Exp $
4.\"
5.\" Copyright (c) 1990, 1991, 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 and the American National Standards Committee X3,
10.\" on Information Processing Systems.
11.\"
12.\" Redistribution and use in source and binary forms, with or without
13.\" modification, are permitted provided that the following conditions
14.\" are met:
15.\" 1. Redistributions of source code must retain the above copyright
16.\" notice, this list of conditions and the following disclaimer.
17.\" 2. Redistributions in binary form must reproduce the above copyright
18.\" notice, this list of conditions and the following disclaimer in the
19.\" documentation and/or other materials provided with the distribution.
20.\" 3. 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: @(#)strcpy.3 8.1 (Berkeley) 6/4/93
37.\"
38.Dd $Mdocdate: May 31 2007 $
39.Dt WMEMCHR 3
40.Os
41.Sh NAME
42.Nm wmemchr ,
43.Nm wmemcmp ,
44.Nm wmemcpy ,
45.Nm wmemmove ,
46.Nm wmemset ,
47.Nm wcscat ,
48.Nm wcschr ,
49.Nm wcscmp ,
50.Nm wcscpy ,
51.Nm wcscspn ,
52.Nm wcslcat ,
53.Nm wcslcpy ,
54.Nm wcslen ,
55.Nm wcsncat ,
56.Nm wcsncmp ,
57.Nm wcsncpy ,
58.Nm wcspbrk ,
59.Nm wcsrchr ,
60.Nm wcsspn ,
61.Nm wcsstr
62.Nd wide character string manipulation operations
63.Sh SYNOPSIS
64.In wchar.h
65.Ft wchar_t *
66.Fn wmemchr "const wchar_t *s" "wchar_t c" "size_t n"
67.Ft int
68.Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t n"
69.Ft wchar_t *
70.Fn wmemcpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n"
71.Ft wchar_t *
72.Fn wmemmove "wchar_t *s1" "const wchar_t *s2" "size_t n"
73.Ft wchar_t *
74.Fn wmemset "wchar_t *s" "wchar_t c" "size_t n"
75.Ft wchar_t *
76.Fn wcscat "wchar_t * restrict s1" "const wchar_t * restrict s2"
77.Ft wchar_t *
78.Fn wcschr "const wchar_t *s" "wchar_t c"
79.Ft int
80.Fn wcscmp "const wchar_t *s1" "const wchar_t *s2"
81.Ft wchar_t *
82.Fn wcscpy "wchar_t * restrict s1" "const wchar_t * restrict s2"
83.Ft size_t
84.Fn wcscspn "const wchar_t *s1" "const wchar_t *s2"
85.Ft size_t
86.Fn wcslcat "wchar_t *s1" "const wchar_t *s2" "size_t n"
87.Ft size_t
88.Fn wcslcpy "wchar_t *s1" "const wchar_t *s2" "size_t n"
89.Ft size_t
90.Fn wcslen "const wchar_t *s"
91.Ft wchar_t *
92.Fn wcsncat "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n"
93.Ft int
94.Fn wcsncmp "const wchar_t *s1" "const wchar_t * s2" "size_t n"
95.Ft wchar_t *
96.Fn wcsncpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n"
97.Ft wchar_t *
98.Fn wcspbrk "const wchar_t *s1" "const wchar_t *s2"
99.Ft wchar_t *
100.Fn wcsrchr "const wchar_t *s" "wchar_t c"
101.Ft size_t
102.Fn wcsspn "const wchar_t *s1" "const wchar_t *s2"
103.Ft wchar_t *
104.Fn wcsstr "const wchar_t *s1" "const wchar_t *s2"
105.Sh DESCRIPTION
106These functions implement string manipulation operations over wide character
107strings.
108For a detailed description, refer to documents for the respective single-byte
109counterpart, such as
110.Xr memchr 3 .
111.Sh SEE ALSO
112.Xr memchr 3 ,
113.Xr memcmp 3 ,
114.Xr memcpy 3 ,
115.Xr memmove 3 ,
116.Xr memset 3 ,
117.Xr strcat 3 ,
118.Xr strchr 3 ,
119.Xr strcmp 3 ,
120.Xr strcpy 3 ,
121.Xr strcspn 3 ,
122.Xr strlcat 3 ,
123.Xr strlcpy 3 ,
124.Xr strlen 3 ,
125.Xr strncat 3 ,
126.Xr strncmp 3 ,
127.Xr strncpy 3 ,
128.Xr strpbrk 3 ,
129.Xr strrchr 3 ,
130.Xr strspn 3 ,
131.Xr strstr 3
132.Sh STANDARDS
133These functions conform to
134.St -isoC-99
135and were first introduced in
136.St -isoC-amd1 ,
137with the exception of
138.Fn wcslcat
139and
140.Fn wcslcpy ,
141which are extensions.
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
34wchar_t *
35wmemchr(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.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
35int
36wmemcmp(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.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
35wchar_t *
36wmemcpy(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.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
35wchar_t *
36wmemmove(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.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
34wchar_t *
35wmemset(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}