summaryrefslogtreecommitdiff
path: root/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc')
-rw-r--r--src/lib/libc/crypt/Makefile.inc14
-rw-r--r--src/lib/libc/crypt/arc4random.3114
-rw-r--r--src/lib/libc/crypt/arc4random.c236
-rw-r--r--src/lib/libc/crypt/bcrypt.c365
-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/chacha_private.h222
-rw-r--r--src/lib/libc/crypt/crypt.3318
-rw-r--r--src/lib/libc/crypt/crypt.c696
-rw-r--r--src/lib/libc/crypt/crypt2.c107
-rw-r--r--src/lib/libc/crypt/md5crypt.c160
-rw-r--r--src/lib/libc/include/ctype_private.h7
-rw-r--r--src/lib/libc/include/namespace.h18
-rw-r--r--src/lib/libc/include/thread_private.h175
-rw-r--r--src/lib/libc/net/Makefile.inc98
-rw-r--r--src/lib/libc/net/base64.c316
-rw-r--r--src/lib/libc/net/byteorder.3206
-rw-r--r--src/lib/libc/net/ethers.3124
-rw-r--r--src/lib/libc/net/ethers.c234
-rw-r--r--src/lib/libc/net/freeaddrinfo.c50
-rw-r--r--src/lib/libc/net/gai_strerror.395
-rw-r--r--src/lib/libc/net/gai_strerror.c78
-rw-r--r--src/lib/libc/net/getaddrinfo.3465
-rw-r--r--src/lib/libc/net/gethostbyname.3297
-rw-r--r--src/lib/libc/net/getifaddrs.3160
-rw-r--r--src/lib/libc/net/getifaddrs.c296
-rw-r--r--src/lib/libc/net/getnameinfo.3265
-rw-r--r--src/lib/libc/net/getnetbyaddr.c47
-rw-r--r--src/lib/libc/net/getnetbyname.c54
-rw-r--r--src/lib/libc/net/getnetent.3140
-rw-r--r--src/lib/libc/net/getnetent.c120
-rw-r--r--src/lib/libc/net/getpeereid.3121
-rw-r--r--src/lib/libc/net/getpeereid.c36
-rw-r--r--src/lib/libc/net/getproto.c59
-rw-r--r--src/lib/libc/net/getprotoent.3213
-rw-r--r--src/lib/libc/net/getprotoent.c166
-rw-r--r--src/lib/libc/net/getprotoname.c67
-rw-r--r--src/lib/libc/net/getrrsetbyname.3165
-rw-r--r--src/lib/libc/net/getservbyname.c70
-rw-r--r--src/lib/libc/net/getservbyport.c64
-rw-r--r--src/lib/libc/net/getservent.3220
-rw-r--r--src/lib/libc/net/getservent.c168
-rw-r--r--src/lib/libc/net/herror.c106
-rw-r--r--src/lib/libc/net/htonl.c21
-rw-r--r--src/lib/libc/net/htons.c21
-rw-r--r--src/lib/libc/net/if_indextoname.3143
-rw-r--r--src/lib/libc/net/if_indextoname.c86
-rw-r--r--src/lib/libc/net/if_nameindex.c146
-rw-r--r--src/lib/libc/net/if_nametoindex.c81
-rw-r--r--src/lib/libc/net/inet.3355
-rw-r--r--src/lib/libc/net/inet6_opt_init.3328
-rw-r--r--src/lib/libc/net/inet6_option_space.3442
-rw-r--r--src/lib/libc/net/inet6_rth_space.3220
-rw-r--r--src/lib/libc/net/inet6_rthdr_space.3310
-rw-r--r--src/lib/libc/net/inet_addr.c175
-rw-r--r--src/lib/libc/net/inet_lnaof.c51
-rw-r--r--src/lib/libc/net/inet_makeaddr.c54
-rw-r--r--src/lib/libc/net/inet_net.3197
-rw-r--r--src/lib/libc/net/inet_net_ntop.c162
-rw-r--r--src/lib/libc/net/inet_net_pton.c231
-rw-r--r--src/lib/libc/net/inet_neta.c80
-rw-r--r--src/lib/libc/net/inet_netof.c50
-rw-r--r--src/lib/libc/net/inet_network.c84
-rw-r--r--src/lib/libc/net/inet_ntoa.c51
-rw-r--r--src/lib/libc/net/inet_ntop.c205
-rw-r--r--src/lib/libc/net/inet_pton.c213
-rw-r--r--src/lib/libc/net/ip6opt.c593
-rw-r--r--src/lib/libc/net/link_addr.3127
-rw-r--r--src/lib/libc/net/linkaddr.c148
-rw-r--r--src/lib/libc/net/ntohl.c21
-rw-r--r--src/lib/libc/net/ntohs.c21
-rw-r--r--src/lib/libc/net/rcmd.3266
-rw-r--r--src/lib/libc/net/rcmd.c303
-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.c40
-rw-r--r--src/lib/libc/net/res_comp.c475
-rw-r--r--src/lib/libc/net/res_data.c105
-rw-r--r--src/lib/libc/net/res_debug_syms.c189
-rw-r--r--src/lib/libc/net/res_random.c275
-rw-r--r--src/lib/libc/net/resolver.3398
-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/ruserok.c438
-rw-r--r--src/lib/libc/net/send.c40
-rw-r--r--src/lib/libc/net/vars6.c42
-rw-r--r--src/lib/libc/stdlib/Makefile.inc63
-rw-r--r--src/lib/libc/stdlib/_Exit.c22
-rw-r--r--src/lib/libc/stdlib/_rand48.c47
-rw-r--r--src/lib/libc/stdlib/a64l.3133
-rw-r--r--src/lib/libc/stdlib/a64l.c42
-rw-r--r--src/lib/libc/stdlib/abort.368
-rw-r--r--src/lib/libc/stdlib/abort.c80
-rw-r--r--src/lib/libc/stdlib/abs.370
-rw-r--r--src/lib/libc/stdlib/abs.c37
-rw-r--r--src/lib/libc/stdlib/alloca.376
-rw-r--r--src/lib/libc/stdlib/atexit.377
-rw-r--r--src/lib/libc/stdlib/atexit.c194
-rw-r--r--src/lib/libc/stdlib/atexit.h50
-rw-r--r--src/lib/libc/stdlib/atof.374
-rw-r--r--src/lib/libc/stdlib/atof.c37
-rw-r--r--src/lib/libc/stdlib/atoi.391
-rw-r--r--src/lib/libc/stdlib/atoi.c37
-rw-r--r--src/lib/libc/stdlib/atol.370
-rw-r--r--src/lib/libc/stdlib/atol.c37
-rw-r--r--src/lib/libc/stdlib/atoll.370
-rw-r--r--src/lib/libc/stdlib/atoll.c38
-rw-r--r--src/lib/libc/stdlib/bsearch.384
-rw-r--r--src/lib/libc/stdlib/bsearch.c67
-rw-r--r--src/lib/libc/stdlib/cfree.c39
-rw-r--r--src/lib/libc/stdlib/div.364
-rw-r--r--src/lib/libc/stdlib/div.c71
-rw-r--r--src/lib/libc/stdlib/drand48.c23
-rw-r--r--src/lib/libc/stdlib/ecvt.3168
-rw-r--r--src/lib/libc/stdlib/ecvt.c106
-rw-r--r--src/lib/libc/stdlib/erand48.c24
-rw-r--r--src/lib/libc/stdlib/exit.3102
-rw-r--r--src/lib/libc/stdlib/exit.c59
-rw-r--r--src/lib/libc/stdlib/gcvt.c123
-rw-r--r--src/lib/libc/stdlib/getenv.3175
-rw-r--r--src/lib/libc/stdlib/getenv.c81
-rw-r--r--src/lib/libc/stdlib/getopt.3364
-rw-r--r--src/lib/libc/stdlib/getopt_long.3445
-rw-r--r--src/lib/libc/stdlib/getopt_long.c518
-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.3239
-rw-r--r--src/lib/libc/stdlib/hcreate.c191
-rw-r--r--src/lib/libc/stdlib/heapsort.c173
-rw-r--r--src/lib/libc/stdlib/imaxabs.365
-rw-r--r--src/lib/libc/stdlib/imaxabs.c38
-rw-r--r--src/lib/libc/stdlib/imaxdiv.366
-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.c22
-rw-r--r--src/lib/libc/stdlib/l64a.c42
-rw-r--r--src/lib/libc/stdlib/labs.369
-rw-r--r--src/lib/libc/stdlib/labs.c37
-rw-r--r--src/lib/libc/stdlib/lcong48.c31
-rw-r--r--src/lib/libc/stdlib/ldiv.372
-rw-r--r--src/lib/libc/stdlib/ldiv.c50
-rw-r--r--src/lib/libc/stdlib/llabs.c38
-rw-r--r--src/lib/libc/stdlib/lldiv.366
-rw-r--r--src/lib/libc/stdlib/lldiv.c50
-rw-r--r--src/lib/libc/stdlib/lrand48.c24
-rw-r--r--src/lib/libc/stdlib/lsearch.3108
-rw-r--r--src/lib/libc/stdlib/lsearch.c84
-rw-r--r--src/lib/libc/stdlib/malloc.3484
-rw-r--r--src/lib/libc/stdlib/malloc.c1820
-rw-r--r--src/lib/libc/stdlib/merge.c333
-rw-r--r--src/lib/libc/stdlib/mrand48.c24
-rw-r--r--src/lib/libc/stdlib/nrand48.c22
-rw-r--r--src/lib/libc/stdlib/posix_memalign.392
-rw-r--r--src/lib/libc/stdlib/posix_openpt.3102
-rw-r--r--src/lib/libc/stdlib/posix_pty.c119
-rw-r--r--src/lib/libc/stdlib/ptsname.3160
-rw-r--r--src/lib/libc/stdlib/qabs.356
-rw-r--r--src/lib/libc/stdlib/qabs.c37
-rw-r--r--src/lib/libc/stdlib/qdiv.361
-rw-r--r--src/lib/libc/stdlib/qdiv.c50
-rw-r--r--src/lib/libc/stdlib/qsort.3238
-rw-r--r--src/lib/libc/stdlib/qsort.c162
-rw-r--r--src/lib/libc/stdlib/radixsort.3155
-rw-r--r--src/lib/libc/stdlib/radixsort.c294
-rw-r--r--src/lib/libc/stdlib/rand.3105
-rw-r--r--src/lib/libc/stdlib/rand.c67
-rw-r--r--src/lib/libc/stdlib/rand48.3179
-rw-r--r--src/lib/libc/stdlib/rand48.h32
-rw-r--r--src/lib/libc/stdlib/random.3185
-rw-r--r--src/lib/libc/stdlib/random.c446
-rw-r--r--src/lib/libc/stdlib/realpath.3130
-rw-r--r--src/lib/libc/stdlib/realpath.c214
-rw-r--r--src/lib/libc/stdlib/remque.c44
-rw-r--r--src/lib/libc/stdlib/seed48.c37
-rw-r--r--src/lib/libc/stdlib/setenv.c180
-rw-r--r--src/lib/libc/stdlib/srand48.c31
-rw-r--r--src/lib/libc/stdlib/strtod.3167
-rw-r--r--src/lib/libc/stdlib/strtoimax.c140
-rw-r--r--src/lib/libc/stdlib/strtol.3264
-rw-r--r--src/lib/libc/stdlib/strtol.c151
-rw-r--r--src/lib/libc/stdlib/strtoll.c144
-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.3245
-rw-r--r--src/lib/libc/stdlib/strtoul.c102
-rw-r--r--src/lib/libc/stdlib/strtoull.c106
-rw-r--r--src/lib/libc/stdlib/strtoumax.c102
-rw-r--r--src/lib/libc/stdlib/system.3109
-rw-r--r--src/lib/libc/stdlib/system.c74
-rw-r--r--src/lib/libc/stdlib/tfind.c41
-rw-r--r--src/lib/libc/stdlib/tsearch.3130
-rw-r--r--src/lib/libc/stdlib/tsearch.c119
-rw-r--r--src/lib/libc/string/Makefile.inc175
-rw-r--r--src/lib/libc/string/bcmp.388
-rw-r--r--src/lib/libc/string/bcmp.c55
-rw-r--r--src/lib/libc/string/bcopy.367
-rw-r--r--src/lib/libc/string/bcopy.c128
-rw-r--r--src/lib/libc/string/bstring.3108
-rw-r--r--src/lib/libc/string/bzero.374
-rw-r--r--src/lib/libc/string/bzero.c48
-rw-r--r--src/lib/libc/string/explicit_bzero.c20
-rw-r--r--src/lib/libc/string/ffs.361
-rw-r--r--src/lib/libc/string/ffs.c44
-rw-r--r--src/lib/libc/string/index.c47
-rw-r--r--src/lib/libc/string/memccpy.381
-rw-r--r--src/lib/libc/string/memccpy.c48
-rw-r--r--src/lib/libc/string/memchr.3102
-rw-r--r--src/lib/libc/string/memchr.c48
-rw-r--r--src/lib/libc/string/memcmp.385
-rw-r--r--src/lib/libc/string/memcmp.c51
-rw-r--r--src/lib/libc/string/memcpy.379
-rw-r--r--src/lib/libc/string/memmem.377
-rw-r--r--src/lib/libc/string/memmem.c63
-rw-r--r--src/lib/libc/string/memmove.376
-rw-r--r--src/lib/libc/string/memrchr.c38
-rw-r--r--src/lib/libc/string/memset.375
-rw-r--r--src/lib/libc/string/memset.c47
-rw-r--r--src/lib/libc/string/rindex.c49
-rw-r--r--src/lib/libc/string/stpcpy.3184
-rw-r--r--src/lib/libc/string/stpcpy.c44
-rw-r--r--src/lib/libc/string/stpncpy.c56
-rw-r--r--src/lib/libc/string/strcasecmp.392
-rw-r--r--src/lib/libc/string/strcasecmp.c105
-rw-r--r--src/lib/libc/string/strcasestr.c60
-rw-r--r--src/lib/libc/string/strcat.381
-rw-r--r--src/lib/libc/string/strcat.c51
-rw-r--r--src/lib/libc/string/strchr.3114
-rw-r--r--src/lib/libc/string/strcmp.397
-rw-r--r--src/lib/libc/string/strcmp.c51
-rw-r--r--src/lib/libc/string/strcoll.373
-rw-r--r--src/lib/libc/string/strcoll.c44
-rw-r--r--src/lib/libc/string/strcpy.392
-rw-r--r--src/lib/libc/string/strcpy.c50
-rw-r--r--src/lib/libc/string/strcspn.3108
-rw-r--r--src/lib/libc/string/strcspn.c58
-rw-r--r--src/lib/libc/string/strdup.3112
-rw-r--r--src/lib/libc/string/strdup.c49
-rw-r--r--src/lib/libc/string/strerror.3123
-rw-r--r--src/lib/libc/string/strerror.c41
-rw-r--r--src/lib/libc/string/strerror_r.c137
-rw-r--r--src/lib/libc/string/string.3136
-rw-r--r--src/lib/libc/string/strlcat.c55
-rw-r--r--src/lib/libc/string/strlcpy.3188
-rw-r--r--src/lib/libc/string/strlcpy.c51
-rw-r--r--src/lib/libc/string/strlen.3105
-rw-r--r--src/lib/libc/string/strlen.c47
-rw-r--r--src/lib/libc/string/strmode.3157
-rw-r--r--src/lib/libc/string/strmode.c140
-rw-r--r--src/lib/libc/string/strncat.3128
-rw-r--r--src/lib/libc/string/strncat.c57
-rw-r--r--src/lib/libc/string/strncmp.c51
-rw-r--r--src/lib/libc/string/strncpy.3153
-rw-r--r--src/lib/libc/string/strncpy.c62
-rw-r--r--src/lib/libc/string/strndup.c39
-rw-r--r--src/lib/libc/string/strnlen.c36
-rw-r--r--src/lib/libc/string/strpbrk.380
-rw-r--r--src/lib/libc/string/strpbrk.c48
-rw-r--r--src/lib/libc/string/strrchr.3116
-rw-r--r--src/lib/libc/string/strsep.3110
-rw-r--r--src/lib/libc/string/strsep.c70
-rw-r--r--src/lib/libc/string/strsignal.368
-rw-r--r--src/lib/libc/string/strsignal.c41
-rw-r--r--src/lib/libc/string/strspn.392
-rw-r--r--src/lib/libc/string/strspn.c51
-rw-r--r--src/lib/libc/string/strstr.3100
-rw-r--r--src/lib/libc/string/strstr.c56
-rw-r--r--src/lib/libc/string/strtok.3166
-rw-r--r--src/lib/libc/string/strtok.c86
-rw-r--r--src/lib/libc/string/strxfrm.379
-rw-r--r--src/lib/libc/string/strxfrm.c51
-rw-r--r--src/lib/libc/string/swab.361
-rw-r--r--src/lib/libc/string/swab.c61
-rw-r--r--src/lib/libc/string/timingsafe_bcmp.c33
-rw-r--r--src/lib/libc/string/wcscasecmp.394
-rw-r--r--src/lib/libc/string/wcscasecmp.c61
-rw-r--r--src/lib/libc/string/wcscat.3115
-rw-r--r--src/lib/libc/string/wcscat.c55
-rw-r--r--src/lib/libc/string/wcschr.385
-rw-r--r--src/lib/libc/string/wcschr.c50
-rw-r--r--src/lib/libc/string/wcscmp.392
-rw-r--r--src/lib/libc/string/wcscmp.c51
-rw-r--r--src/lib/libc/string/wcscpy.3129
-rw-r--r--src/lib/libc/string/wcscpy.c52
-rw-r--r--src/lib/libc/string/wcscspn.383
-rw-r--r--src/lib/libc/string/wcscspn.c53
-rw-r--r--src/lib/libc/string/wcsdup.397
-rw-r--r--src/lib/libc/string/wcsdup.c31
-rw-r--r--src/lib/libc/string/wcslcat.c56
-rw-r--r--src/lib/libc/string/wcslcpy.3153
-rw-r--r--src/lib/libc/string/wcslcpy.c52
-rw-r--r--src/lib/libc/string/wcslen.370
-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.381
-rw-r--r--src/lib/libc/string/wcspbrk.c53
-rw-r--r--src/lib/libc/string/wcsrchr.385
-rw-r--r--src/lib/libc/string/wcsrchr.c50
-rw-r--r--src/lib/libc/string/wcsspn.379
-rw-r--r--src/lib/libc/string/wcsspn.c55
-rw-r--r--src/lib/libc/string/wcsstr.388
-rw-r--r--src/lib/libc/string/wcsstr.c70
-rw-r--r--src/lib/libc/string/wcstok.3151
-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.369
-rw-r--r--src/lib/libc/string/wcswidth.c50
-rw-r--r--src/lib/libc/string/wmemchr.381
-rw-r--r--src/lib/libc/string/wmemchr.c47
-rw-r--r--src/lib/libc/string/wmemcmp.378
-rw-r--r--src/lib/libc/string/wmemcmp.c50
-rw-r--r--src/lib/libc/string/wmemcpy.379
-rw-r--r--src/lib/libc/string/wmemcpy.c40
-rw-r--r--src/lib/libc/string/wmemmove.378
-rw-r--r--src/lib/libc/string/wmemmove.c40
-rw-r--r--src/lib/libc/string/wmemset.373
-rw-r--r--src/lib/libc/string/wmemset.c46
319 files changed, 39027 insertions, 0 deletions
diff --git a/src/lib/libc/crypt/Makefile.inc b/src/lib/libc/crypt/Makefile.inc
new file mode 100644
index 0000000000..c852523372
--- /dev/null
+++ b/src/lib/libc/crypt/Makefile.inc
@@ -0,0 +1,14 @@
1# $OpenBSD: Makefile.inc,v 1.19 2013/10/21 20:33:23 deraadt Exp $
2
3.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/crypt ${LIBCSRCDIR}/crypt
4
5SRCS+= crypt.c crypt2.c md5crypt.c arc4random.c blowfish.c bcrypt.c
6
7MAN+= crypt.3 blowfish.3 arc4random.3
8MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_cipher.3
9MLINKS+=crypt.3 bcrypt_gensalt.3 crypt.3 bcrypt.3 crypt.3 md5crypt.3
10MLINKS+=crypt.3 des_setkey.3 blowfish.3 blf_key.3 blowfish.3 blf_enc.3
11MLINKS+=blowfish.3 blf_dec.3 blowfish.3 blf_ecb_encrypt.3
12MLINKS+=blowfish.3 blf_ecb_decrypt.3 blowfish.3 blf_cbc_encrypt.3
13MLINKS+=blowfish.3 blf_cbc_decrypt.3
14MLINKS+=arc4random.3 arc4random_buf.3 arc4random.3 arc4random_uniform.3
diff --git a/src/lib/libc/crypt/arc4random.3 b/src/lib/libc/crypt/arc4random.3
new file mode 100644
index 0000000000..476bc28017
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.3
@@ -0,0 +1,114 @@
1.\" $OpenBSD: arc4random.3,v 1.32 2013/10/22 06:51:41 jmc Exp $
2.\"
3.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by Niels Provos.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\" derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.\" Manual page, using -mandoc macros
32.\"
33.Dd $Mdocdate: October 22 2013 $
34.Dt ARC4RANDOM 3
35.Os
36.Sh NAME
37.Nm arc4random ,
38.Nm arc4random_buf ,
39.Nm arc4random_uniform
40.Nd random number generator
41.Sh SYNOPSIS
42.In stdlib.h
43.Ft u_int32_t
44.Fn arc4random "void"
45.Ft void
46.Fn arc4random_buf "void *buf" "size_t nbytes"
47.Ft u_int32_t
48.Fn arc4random_uniform "u_int32_t upper_bound"
49.Sh DESCRIPTION
50This family of functions provides higher quality data than those
51described in
52.Xr rand 3 ,
53.Xr random 3 ,
54and
55.Xr drand48 3 .
56.Pp
57Use of these functions is encouraged for almost all random number
58consumption because the other interfaces are deficient in either
59quality, portability, standardization, or availability.
60These functions can be called in almost all coding environments,
61including
62.Xr pthreads 3
63and
64.Xr chroot 2 .
65.Pp
66High quality 32-bit pseudo-random numbers are generated very quickly.
67On each call, a cryptographic pseudo-random number generator is used
68to generate a new result.
69One data pool is used for all consumers in a process, so that consumption
70under program flow can act as additional stirring.
71The subsystem is re-seeded from the kernel random number subsystem using
72.Xr sysctl 3
73on a regular basis, and also upon
74.Xr fork 2 .
75.Pp
76The
77.Fn arc4random
78function returns a single 32-bit value.
79.Pp
80.Fn arc4random_buf
81fills the region
82.Fa buf
83of length
84.Fa nbytes
85with random data.
86.Pp
87.Fn arc4random_uniform
88will return a single 32-bit value, uniformly distributed but less than
89.Fa upper_bound .
90This is recommended over constructions like
91.Dq Li arc4random() % upper_bound
92as it avoids "modulo bias" when the upper bound is not a power of two.
93In the worst case, this function may consume multiple iterations
94to ensure uniformity; see the source code to understand the problem
95and solution.
96.Sh RETURN VALUES
97These functions are always successful, and no return value is
98reserved to indicate an error.
99.Sh SEE ALSO
100.Xr rand 3 ,
101.Xr rand48 3 ,
102.Xr random 3
103.Sh HISTORY
104These functions first appeared in
105.Ox 2.1 .
106.Pp
107The original version of this random number generator used the
108RC4 (also known as ARC4) algorithm.
109In
110.Ox 5.5
111it was replaced with the ChaCha20 cipher, and it may be replaced
112again in the future as cryptographic techniques advance.
113A good mnemonic is
114.Dq A Replacement Call for Random .
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
new file mode 100644
index 0000000000..e836395803
--- /dev/null
+++ b/src/lib/libc/crypt/arc4random.c
@@ -0,0 +1,236 @@
1/* $OpenBSD: arc4random.c,v 1.26 2013/10/21 20:33:23 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * ChaCha based random number generator for OpenBSD.
23 */
24
25#include <fcntl.h>
26#include <limits.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include <sys/types.h>
31#include <sys/param.h>
32#include <sys/time.h>
33#include <sys/sysctl.h>
34#include "thread_private.h"
35
36#define KEYSTREAM_ONLY
37#include "chacha_private.h"
38
39#ifdef __GNUC__
40#define inline __inline
41#else /* !__GNUC__ */
42#define inline
43#endif /* !__GNUC__ */
44
45#define KEYSZ 32
46#define IVSZ 8
47#define BLOCKSZ 64
48#define RSBUFSZ (16*BLOCKSZ)
49static int rs_initialized;
50static pid_t rs_stir_pid;
51static chacha_ctx rs; /* chacha context for random keystream */
52static u_char rs_buf[RSBUFSZ]; /* keystream blocks */
53static size_t rs_have; /* valid bytes at end of rs_buf */
54static size_t rs_count; /* bytes till reseed */
55
56static inline void _rs_rekey(u_char *dat, size_t datlen);
57
58static inline void
59_rs_init(u_char *buf, size_t n)
60{
61 if (n < KEYSZ + IVSZ)
62 return;
63 chacha_keysetup(&rs, buf, KEYSZ * 8, 0);
64 chacha_ivsetup(&rs, buf + KEYSZ);
65}
66
67static void
68_rs_stir(void)
69{
70 int mib[2];
71 size_t len;
72 u_char rnd[KEYSZ + IVSZ];
73
74 mib[0] = CTL_KERN;
75 mib[1] = KERN_ARND;
76
77 len = sizeof(rnd);
78 sysctl(mib, 2, rnd, &len, NULL, 0);
79
80 if (!rs_initialized) {
81 rs_initialized = 1;
82 _rs_init(rnd, sizeof(rnd));
83 } else
84 _rs_rekey(rnd, sizeof(rnd));
85 memset(rnd, 0, sizeof(rnd));
86
87 /* invalidate rs_buf */
88 rs_have = 0;
89 memset(rs_buf, 0, RSBUFSZ);
90
91 rs_count = 1600000;
92}
93
94static inline void
95_rs_stir_if_needed(size_t len)
96{
97 pid_t pid = getpid();
98
99 if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) {
100 rs_stir_pid = pid;
101 _rs_stir();
102 } else
103 rs_count -= len;
104}
105
106static inline void
107_rs_rekey(u_char *dat, size_t datlen)
108{
109#ifndef KEYSTREAM_ONLY
110 memset(rs_buf, 0,RSBUFSZ);
111#endif
112 /* fill rs_buf with the keystream */
113 chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ);
114 /* mix in optional user provided data */
115 if (dat) {
116 size_t i, m;
117
118 m = MIN(datlen, KEYSZ + IVSZ);
119 for (i = 0; i < m; i++)
120 rs_buf[i] ^= dat[i];
121 }
122 /* immediately reinit for backtracking resistance */
123 _rs_init(rs_buf, KEYSZ + IVSZ);
124 memset(rs_buf, 0, KEYSZ + IVSZ);
125 rs_have = RSBUFSZ - KEYSZ - IVSZ;
126}
127
128static inline void
129_rs_random_buf(void *_buf, size_t n)
130{
131 u_char *buf = (u_char *)_buf;
132 size_t m;
133
134 _rs_stir_if_needed(n);
135 while (n > 0) {
136 if (rs_have > 0) {
137 m = MIN(n, rs_have);
138 memcpy(buf, rs_buf + RSBUFSZ - rs_have, m);
139 memset(rs_buf + RSBUFSZ - rs_have, 0, m);
140 buf += m;
141 n -= m;
142 rs_have -= m;
143 }
144 if (rs_have == 0)
145 _rs_rekey(NULL, 0);
146 }
147}
148
149static inline void
150_rs_random_u32(u_int32_t *val)
151{
152 _rs_stir_if_needed(sizeof(*val));
153 if (rs_have < sizeof(*val))
154 _rs_rekey(NULL, 0);
155 memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val));
156 memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val));
157 rs_have -= sizeof(*val);
158 return;
159}
160
161u_int32_t
162arc4random(void)
163{
164 u_int32_t val;
165
166 _ARC4_LOCK();
167 _rs_random_u32(&val);
168 _ARC4_UNLOCK();
169 return val;
170}
171
172void
173arc4random_buf(void *buf, size_t n)
174{
175 _ARC4_LOCK();
176 _rs_random_buf(buf, n);
177 _ARC4_UNLOCK();
178}
179
180/*
181 * Calculate a uniformly distributed random number less than upper_bound
182 * avoiding "modulo bias".
183 *
184 * Uniformity is achieved by generating new random numbers until the one
185 * returned is outside the range [0, 2**32 % upper_bound). This
186 * guarantees the selected random number will be inside
187 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
188 * after reduction modulo upper_bound.
189 */
190u_int32_t
191arc4random_uniform(u_int32_t upper_bound)
192{
193 u_int32_t r, min;
194
195 if (upper_bound < 2)
196 return 0;
197
198 /* 2**32 % x == (2**32 - x) % x */
199 min = -upper_bound % upper_bound;
200
201 /*
202 * This could theoretically loop forever but each retry has
203 * p > 0.5 (worst case, usually far better) of selecting a
204 * number inside the range we need, so it should rarely need
205 * to re-roll.
206 */
207 for (;;) {
208 r = arc4random();
209 if (r >= min)
210 break;
211 }
212
213 return r % upper_bound;
214}
215
216#if 0
217/*-------- Test code for i386 --------*/
218#include <stdio.h>
219#include <machine/pctr.h>
220int
221main(int argc, char **argv)
222{
223 const int iter = 1000000;
224 int i;
225 pctrval v;
226
227 v = rdtsc();
228 for (i = 0; i < iter; i++)
229 arc4random();
230 v = rdtsc() - v;
231 v /= iter;
232
233 printf("%qd cycles\n", v);
234 exit(0);
235}
236#endif
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
new file mode 100644
index 0000000000..d7af344b97
--- /dev/null
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -0,0 +1,365 @@
1/* $OpenBSD: bcrypt.c,v 1.37 2014/04/08 20:14:25 tedu Exp $ */
2
3/*
4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
5 * Copyright (c) 1997 Niels Provos <provos@umich.edu>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19/* This password hashing algorithm was designed by David Mazieres
20 * <dm@lcs.mit.edu> and works as follows:
21 *
22 * 1. state := InitState ()
23 * 2. state := ExpandKey (state, salt, password)
24 * 3. REPEAT rounds:
25 * state := ExpandKey (state, 0, password)
26 * state := ExpandKey (state, 0, salt)
27 * 4. ctext := "OrpheanBeholderScryDoubt"
28 * 5. REPEAT 64:
29 * ctext := Encrypt_ECB (state, ctext);
30 * 6. RETURN Concatenate (salt, ctext);
31 *
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <sys/types.h>
37#include <string.h>
38#include <pwd.h>
39#include <blf.h>
40
41/* This implementation is adaptable to current computing power.
42 * You can have up to 2^31 rounds which should be enough for some
43 * time to come.
44 */
45
46#define BCRYPT_VERSION '2'
47#define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
48#define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
49#define BCRYPT_MINLOGROUNDS 4 /* we have log2(rounds) in salt */
50
51#define BCRYPT_SALTSPACE (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
52
53char *bcrypt_gensalt(u_int8_t);
54
55static int encode_base64(char *, const u_int8_t *, size_t);
56static int decode_base64(u_int8_t *, size_t, const char *);
57
58/*
59 * Generates a salt for this version of crypt.
60 */
61static int
62bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
63{
64 uint8_t csalt[BCRYPT_MAXSALT];
65
66 if (saltbuflen < BCRYPT_SALTSPACE)
67 return -1;
68
69 arc4random_buf(csalt, sizeof(csalt));
70
71 if (log_rounds < 4)
72 log_rounds = 4;
73 else if (log_rounds > 31)
74 log_rounds = 31;
75
76 snprintf(salt, saltbuflen, "$2a$%2.2u$", log_rounds);
77 encode_base64(salt + 7, csalt, sizeof(csalt));
78
79 return 0;
80}
81
82/*
83 * the core bcrypt function
84 */
85static int
86bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
87 size_t encryptedlen)
88{
89 blf_ctx state;
90 u_int32_t rounds, i, k;
91 u_int16_t j;
92 size_t key_len;
93 u_int8_t salt_len, logr, minor;
94 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
95 u_int8_t csalt[BCRYPT_MAXSALT];
96 u_int32_t cdata[BCRYPT_BLOCKS];
97 char arounds[3];
98
99 /* Discard "$" identifier */
100 salt++;
101
102 if (*salt > BCRYPT_VERSION) {
103 return -1;
104 }
105
106 /* Check for minor versions */
107 if (salt[1] != '$') {
108 switch (salt[1]) {
109 case 'a': /* 'ab' should not yield the same as 'abab' */
110 case 'b': /* cap input length at 72 bytes */
111 minor = salt[1];
112 salt++;
113 break;
114 default:
115 return -1;
116 }
117 } else
118 minor = 0;
119
120 /* Discard version + "$" identifier */
121 salt += 2;
122
123 if (salt[2] != '$')
124 /* Out of sync with passwd entry */
125 return -1;
126
127 memcpy(arounds, salt, sizeof(arounds));
128 if (arounds[sizeof(arounds) - 1] != '$')
129 return -1;
130 arounds[sizeof(arounds) - 1] = 0;
131 logr = strtonum(arounds, BCRYPT_MINLOGROUNDS, 31, NULL);
132 if (logr == 0)
133 return -1;
134 /* Computer power doesn't increase linearly, 2^x should be fine */
135 rounds = 1U << logr;
136
137 /* Discard num rounds + "$" identifier */
138 salt += 3;
139
140 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
141 return -1;
142
143 /* We dont want the base64 salt but the raw data */
144 decode_base64(csalt, BCRYPT_MAXSALT, salt);
145 salt_len = BCRYPT_MAXSALT;
146 if (minor <= 'a')
147 key_len = (u_int8_t)(strlen(key) + (minor >= 'a' ? 1 : 0));
148 else {
149 /* strlen() returns a size_t, but the function calls
150 * below result in implicit casts to a narrower integer
151 * type, so cap key_len at the actual maximum supported
152 * length here to avoid integer wraparound */
153 key_len = strlen(key);
154 if (key_len > 72)
155 key_len = 72;
156 key_len++; /* include the NUL */
157 }
158
159 /* Setting up S-Boxes and Subkeys */
160 Blowfish_initstate(&state);
161 Blowfish_expandstate(&state, csalt, salt_len,
162 (u_int8_t *) key, key_len);
163 for (k = 0; k < rounds; k++) {
164 Blowfish_expand0state(&state, (u_int8_t *) key, key_len);
165 Blowfish_expand0state(&state, csalt, salt_len);
166 }
167
168 /* This can be precomputed later */
169 j = 0;
170 for (i = 0; i < BCRYPT_BLOCKS; i++)
171 cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
172
173 /* Now do the encryption */
174 for (k = 0; k < 64; k++)
175 blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
176
177 for (i = 0; i < BCRYPT_BLOCKS; i++) {
178 ciphertext[4 * i + 3] = cdata[i] & 0xff;
179 cdata[i] = cdata[i] >> 8;
180 ciphertext[4 * i + 2] = cdata[i] & 0xff;
181 cdata[i] = cdata[i] >> 8;
182 ciphertext[4 * i + 1] = cdata[i] & 0xff;
183 cdata[i] = cdata[i] >> 8;
184 ciphertext[4 * i + 0] = cdata[i] & 0xff;
185 }
186
187
188 i = 0;
189 encrypted[i++] = '$';
190 encrypted[i++] = BCRYPT_VERSION;
191 if (minor)
192 encrypted[i++] = minor;
193 encrypted[i++] = '$';
194
195 snprintf(encrypted + i, 4, "%2.2u$", logr);
196
197 encode_base64(encrypted + i + 3, csalt, BCRYPT_MAXSALT);
198 encode_base64(encrypted + strlen(encrypted), ciphertext,
199 4 * BCRYPT_BLOCKS - 1);
200 memset(&state, 0, sizeof(state));
201 memset(ciphertext, 0, sizeof(ciphertext));
202 memset(csalt, 0, sizeof(csalt));
203 memset(cdata, 0, sizeof(cdata));
204 return 0;
205}
206
207/*
208 * user friendly functions
209 */
210int
211bcrypt_newhash(const char *pass, int log_rounds, char *hash, size_t hashlen)
212{
213 char salt[BCRYPT_SALTSPACE];
214
215 if (bcrypt_initsalt(log_rounds, salt, sizeof(salt)) != 0)
216 return -1;
217
218 if (bcrypt_hashpass(pass, salt, hash, hashlen) != 0)
219 return -1;
220
221 explicit_bzero(salt, sizeof(salt));
222 return 0;
223}
224
225int
226bcrypt_checkpass(const char *pass, const char *goodhash)
227{
228 char hash[_PASSWORD_LEN];
229
230 if (bcrypt_hashpass(pass, goodhash, hash, sizeof(hash)) != 0)
231 return -1;
232 if (strlen(hash) != strlen(goodhash) ||
233 timingsafe_bcmp(hash, goodhash, strlen(goodhash)) != 0)
234 return -1;
235
236 explicit_bzero(hash, sizeof(hash));
237 return 0;
238}
239
240/*
241 * internal utilities
242 */
243const static u_int8_t Base64Code[] =
244"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
245
246const static u_int8_t index_64[128] = {
247 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
248 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
249 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
250 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
251 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
252 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
253 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
254 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
255 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
256 255, 255, 255, 255, 255, 255, 28, 29, 30,
257 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
258 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
259 51, 52, 53, 255, 255, 255, 255, 255
260};
261#define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
262
263/*
264 * read buflen (after decoding) bytes of data from b64data
265 */
266static int
267decode_base64(u_int8_t *buffer, size_t len, const char *b64data)
268{
269 u_int8_t *bp = buffer;
270 const u_int8_t *p = b64data;
271 u_int8_t c1, c2, c3, c4;
272
273 while (bp < buffer + len) {
274 c1 = CHAR64(*p);
275 c2 = CHAR64(*(p + 1));
276
277 /* Invalid data */
278 if (c1 == 255 || c2 == 255)
279 return -1;
280
281 *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
282 if (bp >= buffer + len)
283 break;
284
285 c3 = CHAR64(*(p + 2));
286 if (c3 == 255)
287 break;
288
289 *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
290 if (bp >= buffer + len)
291 break;
292
293 c4 = CHAR64(*(p + 3));
294 if (c4 == 255)
295 break;
296 *bp++ = ((c3 & 0x03) << 6) | c4;
297
298 p += 4;
299 }
300 return 0;
301}
302
303/*
304 * Turn len bytes of data into base64 encoded data.
305 * This works without = padding.
306 */
307static int
308encode_base64(char *b64buffer, const u_int8_t *data, size_t len)
309{
310 u_int8_t *bp = b64buffer;
311 const u_int8_t *p = data;
312 u_int8_t c1, c2;
313
314 while (p < data + len) {
315 c1 = *p++;
316 *bp++ = Base64Code[(c1 >> 2)];
317 c1 = (c1 & 0x03) << 4;
318 if (p >= data + len) {
319 *bp++ = Base64Code[c1];
320 break;
321 }
322 c2 = *p++;
323 c1 |= (c2 >> 4) & 0x0f;
324 *bp++ = Base64Code[c1];
325 c1 = (c2 & 0x0f) << 2;
326 if (p >= data + len) {
327 *bp++ = Base64Code[c1];
328 break;
329 }
330 c2 = *p++;
331 c1 |= (c2 >> 6) & 0x03;
332 *bp++ = Base64Code[c1];
333 *bp++ = Base64Code[c2 & 0x3f];
334 }
335 *bp = '\0';
336 return 0;
337}
338
339/*
340 * classic interface
341 */
342char *
343bcrypt_gensalt(u_int8_t log_rounds)
344{
345 static char gsalt[BCRYPT_SALTSPACE];
346
347 bcrypt_initsalt(log_rounds, gsalt, sizeof(gsalt));
348
349 return gsalt;
350}
351
352char *
353bcrypt(const char *pass, const char *salt)
354{
355 static char gencrypted[_PASSWORD_LEN];
356 static char gerror[2];
357
358 /* How do I handle errors ? Return ':' */
359 strlcpy(gerror, ":", sizeof(gerror));
360 if (bcrypt_hashpass(pass, salt, gencrypted, sizeof(gencrypted)) != 0)
361 return gerror;
362
363 return gencrypted;
364}
365
diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3
new file mode 100644
index 0000000000..d15bc8901d
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: blowfish.3,v 1.22 2013/07/16 15:21:11 schwarze Exp $
2.\"
3.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by Niels Provos.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\" derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.\" Manual page, using -mandoc macros
32.\"
33.Dd $Mdocdate: July 16 2013 $
34.Dt BLOWFISH 3
35.Os
36.Sh NAME
37.Nm blf_key ,
38.Nm blf_enc ,
39.Nm blf_dec ,
40.Nm blf_ecb_encrypt ,
41.Nm blf_ecb_decrypt ,
42.Nm blf_cbc_encrypt ,
43.Nm blf_cbc_decrypt
44.Nd Blowfish encryption
45.Sh SYNOPSIS
46.In blf.h
47.Ft void
48.Fn blf_key "blf_ctx *state" "const u_int8_t *key" "u_int16_t keylen"
49.Ft void
50.Fn blf_enc "blf_ctx *state" "u_int32_t *data" "u_int16_t blocks"
51.Ft void
52.Fn blf_dec "blf_ctx *state" "u_int32_t *data" "u_int16_t blocks"
53.Ft void
54.Fn blf_ecb_encrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
55.Ft void
56.Fn blf_ecb_decrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen"
57.Ft void
58.Fn blf_cbc_encrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
59.Ft void
60.Fn blf_cbc_decrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen"
61.Sh DESCRIPTION
62.Em Blowfish
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 Mt provos@physnet.uni-hamburg.de
diff --git a/src/lib/libc/crypt/blowfish.c b/src/lib/libc/crypt/blowfish.c
new file mode 100644
index 0000000000..c337df8a0a
--- /dev/null
+++ b/src/lib/libc/crypt/blowfish.c
@@ -0,0 +1,685 @@
1/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
2/*
3 * Blowfish block cipher for OpenBSD
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Niels Provos.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * This code is derived from section 14.3 and the given source
37 * in section V of Applied Cryptography, second edition.
38 * Blowfish is an unpatented fast block cipher designed by
39 * Bruce Schneier.
40 */
41
42#if 0
43#include <stdio.h> /* used for debugging */
44#include <string.h>
45#endif
46
47#include <sys/types.h>
48#include <blf.h>
49
50#undef inline
51#ifdef __GNUC__
52#define inline __inline
53#else /* !__GNUC__ */
54#define inline
55#endif /* !__GNUC__ */
56
57/* Function for Feistel Networks */
58
59#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
60 + (s)[0x100 + (((x)>>16)&0xFF)]) \
61 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
62 + (s)[0x300 + ( (x) &0xFF)])
63
64#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
65
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/chacha_private.h b/src/lib/libc/crypt/chacha_private.h
new file mode 100644
index 0000000000..7c3680fa6d
--- /dev/null
+++ b/src/lib/libc/crypt/chacha_private.h
@@ -0,0 +1,222 @@
1/*
2chacha-merged.c version 20080118
3D. J. Bernstein
4Public domain.
5*/
6
7/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
8
9typedef unsigned char u8;
10typedef unsigned int u32;
11
12typedef struct
13{
14 u32 input[16]; /* could be compressed */
15} chacha_ctx;
16
17#define U8C(v) (v##U)
18#define U32C(v) (v##U)
19
20#define U8V(v) ((u8)(v) & U8C(0xFF))
21#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23#define ROTL32(v, n) \
24 (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26#define U8TO32_LITTLE(p) \
27 (((u32)((p)[0]) ) | \
28 ((u32)((p)[1]) << 8) | \
29 ((u32)((p)[2]) << 16) | \
30 ((u32)((p)[3]) << 24))
31
32#define U32TO8_LITTLE(p, v) \
33 do { \
34 (p)[0] = U8V((v) ); \
35 (p)[1] = U8V((v) >> 8); \
36 (p)[2] = U8V((v) >> 16); \
37 (p)[3] = U8V((v) >> 24); \
38 } while (0)
39
40#define ROTATE(v,c) (ROTL32(v,c))
41#define XOR(v,w) ((v) ^ (w))
42#define PLUS(v,w) (U32V((v) + (w)))
43#define PLUSONE(v) (PLUS((v),1))
44
45#define QUARTERROUND(a,b,c,d) \
46 a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47 c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48 a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49 c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51static const char sigma[16] = "expand 32-byte k";
52static const char tau[16] = "expand 16-byte k";
53
54static void
55chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
56{
57 const char *constants;
58
59 x->input[4] = U8TO32_LITTLE(k + 0);
60 x->input[5] = U8TO32_LITTLE(k + 4);
61 x->input[6] = U8TO32_LITTLE(k + 8);
62 x->input[7] = U8TO32_LITTLE(k + 12);
63 if (kbits == 256) { /* recommended */
64 k += 16;
65 constants = sigma;
66 } else { /* kbits == 128 */
67 constants = tau;
68 }
69 x->input[8] = U8TO32_LITTLE(k + 0);
70 x->input[9] = U8TO32_LITTLE(k + 4);
71 x->input[10] = U8TO32_LITTLE(k + 8);
72 x->input[11] = U8TO32_LITTLE(k + 12);
73 x->input[0] = U8TO32_LITTLE(constants + 0);
74 x->input[1] = U8TO32_LITTLE(constants + 4);
75 x->input[2] = U8TO32_LITTLE(constants + 8);
76 x->input[3] = U8TO32_LITTLE(constants + 12);
77}
78
79static void
80chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81{
82 x->input[12] = 0;
83 x->input[13] = 0;
84 x->input[14] = U8TO32_LITTLE(iv + 0);
85 x->input[15] = U8TO32_LITTLE(iv + 4);
86}
87
88static void
89chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90{
91 u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92 u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93 u8 *ctarget = NULL;
94 u8 tmp[64];
95 u_int i;
96
97 if (!bytes) return;
98
99 j0 = x->input[0];
100 j1 = x->input[1];
101 j2 = x->input[2];
102 j3 = x->input[3];
103 j4 = x->input[4];
104 j5 = x->input[5];
105 j6 = x->input[6];
106 j7 = x->input[7];
107 j8 = x->input[8];
108 j9 = x->input[9];
109 j10 = x->input[10];
110 j11 = x->input[11];
111 j12 = x->input[12];
112 j13 = x->input[13];
113 j14 = x->input[14];
114 j15 = x->input[15];
115
116 for (;;) {
117 if (bytes < 64) {
118 for (i = 0;i < bytes;++i) tmp[i] = m[i];
119 m = tmp;
120 ctarget = c;
121 c = tmp;
122 }
123 x0 = j0;
124 x1 = j1;
125 x2 = j2;
126 x3 = j3;
127 x4 = j4;
128 x5 = j5;
129 x6 = j6;
130 x7 = j7;
131 x8 = j8;
132 x9 = j9;
133 x10 = j10;
134 x11 = j11;
135 x12 = j12;
136 x13 = j13;
137 x14 = j14;
138 x15 = j15;
139 for (i = 20;i > 0;i -= 2) {
140 QUARTERROUND( x0, x4, x8,x12)
141 QUARTERROUND( x1, x5, x9,x13)
142 QUARTERROUND( x2, x6,x10,x14)
143 QUARTERROUND( x3, x7,x11,x15)
144 QUARTERROUND( x0, x5,x10,x15)
145 QUARTERROUND( x1, x6,x11,x12)
146 QUARTERROUND( x2, x7, x8,x13)
147 QUARTERROUND( x3, x4, x9,x14)
148 }
149 x0 = PLUS(x0,j0);
150 x1 = PLUS(x1,j1);
151 x2 = PLUS(x2,j2);
152 x3 = PLUS(x3,j3);
153 x4 = PLUS(x4,j4);
154 x5 = PLUS(x5,j5);
155 x6 = PLUS(x6,j6);
156 x7 = PLUS(x7,j7);
157 x8 = PLUS(x8,j8);
158 x9 = PLUS(x9,j9);
159 x10 = PLUS(x10,j10);
160 x11 = PLUS(x11,j11);
161 x12 = PLUS(x12,j12);
162 x13 = PLUS(x13,j13);
163 x14 = PLUS(x14,j14);
164 x15 = PLUS(x15,j15);
165
166#ifndef KEYSTREAM_ONLY
167 x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168 x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169 x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170 x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171 x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172 x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173 x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174 x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175 x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176 x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177 x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178 x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179 x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180 x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181 x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182 x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183#endif
184
185 j12 = PLUSONE(j12);
186 if (!j12) {
187 j13 = PLUSONE(j13);
188 /* stopping at 2^70 bytes per nonce is user's responsibility */
189 }
190
191 U32TO8_LITTLE(c + 0,x0);
192 U32TO8_LITTLE(c + 4,x1);
193 U32TO8_LITTLE(c + 8,x2);
194 U32TO8_LITTLE(c + 12,x3);
195 U32TO8_LITTLE(c + 16,x4);
196 U32TO8_LITTLE(c + 20,x5);
197 U32TO8_LITTLE(c + 24,x6);
198 U32TO8_LITTLE(c + 28,x7);
199 U32TO8_LITTLE(c + 32,x8);
200 U32TO8_LITTLE(c + 36,x9);
201 U32TO8_LITTLE(c + 40,x10);
202 U32TO8_LITTLE(c + 44,x11);
203 U32TO8_LITTLE(c + 48,x12);
204 U32TO8_LITTLE(c + 52,x13);
205 U32TO8_LITTLE(c + 56,x14);
206 U32TO8_LITTLE(c + 60,x15);
207
208 if (bytes <= 64) {
209 if (bytes < 64) {
210 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211 }
212 x->input[12] = j12;
213 x->input[13] = j13;
214 return;
215 }
216 bytes -= 64;
217 c += 64;
218#ifndef KEYSTREAM_ONLY
219 m += 64;
220#endif
221 }
222}
diff --git a/src/lib/libc/crypt/crypt.3 b/src/lib/libc/crypt/crypt.3
new file mode 100644
index 0000000000..f4a78781da
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.3
@@ -0,0 +1,318 @@
1.\" $OpenBSD: crypt.3,v 1.34 2014/03/19 02:34:45 tedu Exp $
2.\"
3.\" FreeSec: libcrypt
4.\"
5.\" Copyright (c) 1994 David Burren
6.\" All rights reserved.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 4. Neither the name of the author nor the names of other contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" Manual page, using -mandoc macros
33.\"
34.Dd $Mdocdate: March 19 2014 $
35.Dt CRYPT 3
36.Os
37.Sh NAME
38.Nm crypt ,
39.Nm setkey ,
40.Nm encrypt ,
41.Nm des_setkey ,
42.Nm des_cipher ,
43.Nm bcrypt_gensalt ,
44.Nm bcrypt ,
45.Nm md5crypt
46.Nd password hashing
47.Sh SYNOPSIS
48.In stdlib.h
49.Ft int
50.Fn setkey "const char *key"
51.Pp
52.In unistd.h
53.Ft char *
54.Fn crypt "const char *key" "const char *setting"
55.Ft int
56.Fn encrypt "char *block" "int flag"
57.Ft int
58.Fn des_setkey "const char *key"
59.Ft int
60.Fn des_cipher "const char *in" "char *out" "int32_t salt" "int count"
61.In pwd.h
62.Ft char *
63.Fn bcrypt_gensalt "u_int8_t log_rounds"
64.Ft char *
65.Fn bcrypt "const char *key" "const char *salt"
66.Ft char *
67.Fn md5crypt "const char *key" "const char *salt"
68.Sh DESCRIPTION
69The
70.Fn crypt
71function performs password hashing based on the
72.Tn NBS
73Data Encryption Standard (DES).
74Additional code has been added to deter key search attempts and to use
75stronger hashing algorithms.
76.Pp
77The first argument to
78.Fn crypt
79is a
80.Dv NUL Ns -terminated
81string, typically a user's typed password.
82The second is in one of three forms:
83if it begins with an underscore
84.Pq Ql _
85then an extended format is used
86in interpreting both the key and the setting, as outlined below.
87If it begins
88with a string character
89.Pq Ql $
90and a number then a different algorithm is used depending on the number.
91At the moment a
92.Ql $1
93chooses MD5 hashing and a
94.Ql $2
95chooses Blowfish hashing; see below for more information.
96.Ss Extended crypt
97The
98.Ar key
99is divided into groups of 8 characters (the last group is null-padded)
100and the low-order 7 bits of each character (56 bits per group) are
101used to form the DES key as follows:
102the first group of 56 bits becomes the initial DES key.
103For each additional group, the XOR of the encryption of the current DES
104key with itself and the group bits becomes the next DES key.
105.Pp
106The setting is a 9-character array consisting of an underscore followed
107by 4 bytes of iteration count and 4 bytes of salt.
108These are encoded as printable characters, 6 bits per character,
109least significant character first.
110The values 0 to 63 are encoded as
111.Dq \&./0-9A-Za-z .
112This allows 24 bits for both
113.Fa count
114and
115.Fa salt .
116.Ss "MD5" crypt
117For
118.Tn MD5
119crypt the version number,
120.Fa salt
121and the hashed password are separated by the
122.Ql $
123character.
124The maximum length of a password is limited by
125the length counter of the MD5 context, which is about
1262**64.
127A valid MD5 password entry looks like this:
128.Pp
129.Dq $1$caeiHQwX$hsKqOjrFRRN6K32OWkCBf1 .
130.Pp
131The whole MD5 password string is passed as
132.Fa setting
133for interpretation.
134.Ss "Blowfish" crypt
135The
136.Tn Blowfish
137version of crypt has 128 bits of
138.Fa salt
139in order to make building dictionaries of common passwords space consuming.
140The initial state of the
141.Tn Blowfish
142cipher is expanded using the
143.Fa salt
144and the
145.Fa password
146repeating the process a variable number of rounds, which is encoded in
147the password string.
148The maximum password length is 72.
149The final Blowfish password entry is created by encrypting the string
150.Pp
151.Dq OrpheanBeholderScryDoubt
152.Pp
153with the
154.Tn Blowfish
155state 64 times.
156.Pp
157The version number, the logarithm of the number of rounds and
158the concatenation of salt and hashed password are separated by the
159.Ql $
160character.
161An encoded
162.Sq 8
163would specify 256 rounds.
164A valid Blowfish password looks like this:
165.Pp
166.Dq $2a$12$eIAq8PR8sIUnJ1HaohxX2O9x9Qlm2vK97LJ5dsXdmB.eXF42qjchC .
167.Pp
168The whole Blowfish password string is passed as
169.Fa setting
170for interpretation.
171.Ss "Traditional" crypt
172The first 8 bytes of the key are null-padded, and the low-order 7 bits of
173each character is used to form the 56-bit
174.Tn DES
175key.
176.Pp
177The setting is a 2-character array of the ASCII-encoded salt.
178Thus only 12 bits of
179.Fa salt
180are used.
181.Fa count
182is set to 25.
183.Ss DES Algorithm
184The
185.Fa salt
186introduces disorder in the
187.Tn DES
188algorithm in one of 16777216 or 4096 possible ways
189(i.e., with 24 or 12 bits: if bit
190.Em i
191of the
192.Ar salt
193is set, then bits
194.Em i
195and
196.Em i+24
197are swapped in the
198.Tn DES
199E-box output).
200.Pp
201The DES key is used to encrypt a 64-bit constant using
202.Ar count
203iterations of
204.Tn DES .
205The value returned is a
206.Dv NUL Ns -terminated
207string, 20 or 13 bytes (plus NUL) in length, consisting of the
208.Ar setting
209followed by the encoded 64-bit encryption.
210.Pp
211The functions
212.Fn encrypt ,
213.Fn setkey ,
214.Fn des_setkey ,
215and
216.Fn des_cipher
217provide access to the
218.Tn DES
219algorithm itself.
220.Fn setkey
221is passed a 64-byte array of binary values (numeric 0 or 1).
222A 56-bit key is extracted from this array by dividing the
223array into groups of 8, and ignoring the last bit in each group.
224That bit is reserved for a byte parity check by DES, but is ignored
225by these functions.
226.Pp
227The
228.Fa block
229argument to
230.Fn encrypt
231is also a 64-byte array of binary values.
232If the value of
233.Fa flag
234is 0,
235.Fa block
236is encrypted otherwise it is decrypted.
237The result is returned in the original array
238.Fa block
239after using the key specified by
240.Fn setkey
241to process it.
242.Pp
243The argument to
244.Fn des_setkey
245is a character array of length 8.
246The least significant bit (the parity bit) in each character is ignored,
247and the remaining bits are concatenated to form a 56-bit key.
248The function
249.Fn des_cipher
250encrypts (or decrypts if
251.Fa count
252is negative) the 64-bits stored in the 8 characters at
253.Fa in
254using
255.Xr abs 3
256of
257.Fa count
258iterations of
259.Tn DES
260and stores the 64-bit result in the 8 characters at
261.Fa out
262(which may be the same as
263.Fa in ) .
264The
265.Fa salt
266specifies perturbations to the
267.Tn DES
268E-box output as described above.
269.Pp
270The
271.Fn crypt ,
272.Fn setkey ,
273and
274.Fn des_setkey
275functions all manipulate the same key space.
276.Sh RETURN VALUES
277The function
278.Fn crypt
279returns a pointer to the encrypted value on success, and
280.Dv NULL
281on failure.
282The functions
283.Fn setkey ,
284.Fn encrypt ,
285.Fn des_setkey ,
286and
287.Fn des_cipher
288return 0 on success and 1 on failure.
289.Sh SEE ALSO
290.Xr encrypt 1 ,
291.Xr login 1 ,
292.Xr passwd 1 ,
293.Xr blowfish 3 ,
294.Xr getpass 3 ,
295.Xr md5 3 ,
296.Xr passwd 5
297.Sh HISTORY
298A rotor-based
299.Fn crypt
300function appeared in
301.At v3 .
302The current style
303.Fn crypt
304first appeared in
305.At v7 .
306.Sh AUTHORS
307.An David Burren Aq Mt davidb@werj.com.au
308wrote the original DES functions.
309.Sh BUGS
310The
311.Fn crypt
312function returns a pointer to static data, and subsequent calls to
313.Fn crypt
314will modify the same object.
315.Pp
316With DES hashing, passwords containing the byte 0x80 use less key entropy
317than other passwords.
318This is an implementation bug, not a bug in the DES cipher.
diff --git a/src/lib/libc/crypt/crypt.c b/src/lib/libc/crypt/crypt.c
new file mode 100644
index 0000000000..15a784532d
--- /dev/null
+++ b/src/lib/libc/crypt/crypt.c
@@ -0,0 +1,696 @@
1/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 */
48
49#include <sys/types.h>
50#include <sys/param.h>
51#include <pwd.h>
52#include <unistd.h>
53#include <string.h>
54
55#ifdef DEBUG
56# include <stdio.h>
57#endif
58
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..f31818ae2b
--- /dev/null
+++ b/src/lib/libc/crypt/crypt2.c
@@ -0,0 +1,107 @@
1/* $OpenBSD: crypt2.c,v 1.4 2013/04/17 17:40:35 tedu Exp $ */
2
3/*
4 * FreeSec: libcrypt
5 *
6 * Copyright (c) 1994 David Burren
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the author nor the names of other contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *
34 * This is an original implementation of the DES and the crypt(3) interfaces
35 * by David Burren <davidb@werj.com.au>.
36 *
37 * An excellent reference on the underlying algorithm (and related
38 * algorithms) is:
39 *
40 * B. Schneier, Applied Cryptography: protocols, algorithms,
41 * and source code in C, John Wiley & Sons, 1994.
42 *
43 * Note that in that book's description of DES the lookups for the initial,
44 * pbox, and final permutations are inverted (this has been brought to the
45 * attention of the author). A list of errata for this book has been
46 * posted to the sci.crypt newsgroup by the author and is available for FTP.
47 */
48
49#include <sys/types.h>
50#include <sys/param.h>
51#include <pwd.h>
52#include <unistd.h>
53#include <string.h>
54
55#ifdef DEBUG
56# include <stdio.h>
57#endif
58
59extern const u_char _des_bits8[8];
60extern const u_int32_t _des_bits32[32];
61extern int _des_initialised;
62void _des_init(void);
63void _des_setup_salt(int32_t salt);
64int _des_do_des(u_int32_t , u_int32_t , u_int32_t *, u_int32_t *, int);
65
66int
67setkey(const char *key)
68{
69 int i, j;
70 u_int32_t packed_keys[2];
71 u_char *p;
72
73 p = (u_char *) packed_keys;
74
75 for (i = 0; i < 8; i++) {
76 p[i] = 0;
77 for (j = 0; j < 8; j++)
78 if (*key++ & 1)
79 p[i] |= _des_bits8[j];
80 }
81 return(des_setkey((char *)p));
82}
83
84int
85encrypt(char *block, int flag)
86{
87 u_int32_t io[2];
88 u_char *p;
89 int i, j, retval;
90
91 if (!_des_initialised)
92 _des_init();
93
94 _des_setup_salt(0);
95 p = (u_char *)block;
96 for (i = 0; i < 2; i++) {
97 io[i] = 0L;
98 for (j = 0; j < 32; j++)
99 if (*p++ & 1)
100 io[i] |= _des_bits32[j];
101 }
102 retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
103 for (i = 0; i < 2; i++)
104 for (j = 0; j < 32; j++)
105 block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0;
106 return(retval);
107}
diff --git a/src/lib/libc/crypt/md5crypt.c b/src/lib/libc/crypt/md5crypt.c
new file mode 100644
index 0000000000..a855835bcc
--- /dev/null
+++ b/src/lib/libc/crypt/md5crypt.c
@@ -0,0 +1,160 @@
1/* $OpenBSD: md5crypt.c,v 1.17 2014/04/03 15:55:29 beck Exp $ */
2
3/*
4 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * If we meet some day, and you think this stuff is worth it, you
21 * can buy me a beer in return. Poul-Henning Kamp
22 */
23
24#include <unistd.h>
25#include <stdio.h>
26#include <string.h>
27#include <md5.h>
28#include <string.h>
29
30static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
31 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
32
33static void to64(char *, u_int32_t, int);
34
35static void
36to64(char *s, u_int32_t v, int n)
37{
38 while (--n >= 0) {
39 *s++ = itoa64[v&0x3f];
40 v >>= 6;
41 }
42}
43
44/*
45 * UNIX password
46 *
47 * Use MD5 for what it is best at...
48 */
49
50char *md5crypt(const char *pw, const char *salt);
51
52char *
53md5crypt(const char *pw, const char *salt)
54{
55 /*
56 * This string is the magic for this algorithm.
57 * Having it this way, we can get better later on.
58 */
59 static unsigned char *magic = (unsigned char *)"$1$";
60
61 static char passwd[120], *p;
62 static const unsigned char *sp,*ep;
63 unsigned char final[16];
64 int sl,pl,i;
65 MD5_CTX ctx,ctx1;
66 u_int32_t l;
67
68 /* Refine the salt first */
69 sp = (const unsigned char *)salt;
70
71 /* If it starts with the magic string, then skip that */
72 if(!strncmp((const char *)sp,(const char *)magic,strlen((const char *)magic)))
73 sp += strlen((const char *)magic);
74
75 /* It stops at the first '$', max 8 chars */
76 for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
77 continue;
78
79 /* get the length of the true salt */
80 sl = ep - sp;
81
82 MD5Init(&ctx);
83
84 /* The password first, since that is what is most unknown */
85 MD5Update(&ctx,(const unsigned char *)pw,strlen(pw));
86
87 /* Then our magic string */
88 MD5Update(&ctx,magic,strlen((const char *)magic));
89
90 /* Then the raw salt */
91 MD5Update(&ctx,sp,sl);
92
93 /* Then just as many characters of the MD5(pw,salt,pw) */
94 MD5Init(&ctx1);
95 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
96 MD5Update(&ctx1,sp,sl);
97 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
98 MD5Final(final,&ctx1);
99 for(pl = strlen(pw); pl > 0; pl -= 16)
100 MD5Update(&ctx,final,pl>16 ? 16 : pl);
101
102 /* Don't leave anything around in vm they could use. */
103 memset(final,0,sizeof final);
104
105 /* Then something really weird... */
106 for (i = strlen(pw); i ; i >>= 1)
107 if(i&1)
108 MD5Update(&ctx, final, 1);
109 else
110 MD5Update(&ctx, (const unsigned char *)pw, 1);
111
112 /* Now make the output string */
113 snprintf(passwd, sizeof(passwd), "%s%.*s$", (char *)magic,
114 sl, (const char *)sp);
115
116 MD5Final(final,&ctx);
117
118 /*
119 * And now, just to make sure things don't run too fast
120 * On a 60 MHz Pentium this takes 34 msec, so you would
121 * need 30 seconds to build a 1000 entry dictionary...
122 * On a modern machine, with possible GPU optimization,
123 * this will run a lot faster than that.
124 */
125 for(i=0;i<1000;i++) {
126 MD5Init(&ctx1);
127 if(i & 1)
128 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
129 else
130 MD5Update(&ctx1,final,16);
131
132 if(i % 3)
133 MD5Update(&ctx1,sp,sl);
134
135 if(i % 7)
136 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
137
138 if(i & 1)
139 MD5Update(&ctx1,final,16);
140 else
141 MD5Update(&ctx1,(const unsigned char *)pw,strlen(pw));
142 MD5Final(final,&ctx1);
143 }
144
145 p = passwd + strlen(passwd);
146
147 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
148 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
149 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
150 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
151 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
152 l = final[11] ; to64(p,l,2); p += 2;
153 *p = '\0';
154
155 /* Don't leave anything around in vm they could use. */
156 memset(final, 0, sizeof final);
157
158 return passwd;
159}
160
diff --git a/src/lib/libc/include/ctype_private.h b/src/lib/libc/include/ctype_private.h
new file mode 100644
index 0000000000..39cc792ea4
--- /dev/null
+++ b/src/lib/libc/include/ctype_private.h
@@ -0,0 +1,7 @@
1/* $OpenBSD: ctype_private.h,v 1.1 2005/08/08 05:53:00 espie Exp $ */
2/* Written by Marc Espie, public domain */
3#define CTYPE_NUM_CHARS 256
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
new file mode 100644
index 0000000000..4a51f15ddf
--- /dev/null
+++ b/src/lib/libc/include/namespace.h
@@ -0,0 +1,18 @@
1/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */
2
3#define catclose _catclose
4#define catgets _catgets
5#define catopen _catopen
6#define err _err
7#define errx _errx
8#define strtoq _strtoq
9#define strtouq _strtouq
10#define sys_errlist _sys_errlist
11#define sys_nerr _sys_nerr
12#define sys_siglist _sys_siglist
13#define verr _verr
14#define verrx _verrx
15#define vwarn _vwarn
16#define vwarnx _vwarnx
17#define warn _warn
18#define warnx _warnx
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h
new file mode 100644
index 0000000000..673fb9c6a6
--- /dev/null
+++ b/src/lib/libc/include/thread_private.h
@@ -0,0 +1,175 @@
1/* $OpenBSD: thread_private.h,v 1.25 2011/10/16 06:29:56 guenther Exp $ */
2
3/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
4
5#ifndef _THREAD_PRIVATE_H_
6#define _THREAD_PRIVATE_H_
7
8/*
9 * This file defines the thread library interface to libc. Thread
10 * libraries must implement the functions described here for proper
11 * inter-operation with libc. libc contains weak versions of the
12 * described functions for operation in a non-threaded environment.
13 */
14
15/*
16 * This variable is 0 until a second thread is created.
17 */
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 * Ditto for hand-written syscall stubs:
38 *
39 * Use STUB_NAME(n) to get the strong name of the stub: _thread_sys_n
40 * STUB_ALIAS(n) to generate the weak symbol n pointing to _thread_sys_n,
41 * STUB_PROTOTYPE(n) to generate a prototype for _thread_sys_n (based on n).
42 */
43#define STUB_NAME(name) __CONCAT(_thread_sys_,name)
44#define STUB_ALIAS(name) __weak_alias(name, STUB_NAME(name))
45#ifdef __GNUC__
46#define STUB_PROTOTYPE(name) __typeof__(name) STUB_NAME(name)
47#else
48#define STUB_PROTOTYPE(name) /* typeof() only in gcc */
49#endif
50
51/*
52 * helper macro to make unique names in the thread namespace
53 */
54#define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name)
55
56/*
57 * helper functions that exist as (weak) null functions in libc and
58 * (strong) functions in the thread library. These functions:
59 *
60 * _thread_tag_lock:
61 * lock the mutex associated with the given tag. If the given
62 * tag is NULL a tag is first allocated.
63 *
64 * _thread_tag_unlock:
65 * unlock the mutex associated with the given tag. If the given
66 * tag is NULL a tag is first allocated.
67 *
68 * _thread_tag_storage:
69 * return a pointer to per thread instance of data associated
70 * with the given tag. If the given tag is NULL a tag is first
71 * allocated.
72 *
73 * _thread_mutex_lock:
74 * lock the given mutex. If the given mutex is NULL,
75 * rely on rthreads/pthreads implementation to initialize
76 * the mutex before locking.
77 *
78 * _thread_mutex_unlock:
79 * unlock the given mutex.
80 *
81 * _thread_mutex_destroy:
82 * destroy the given mutex.
83 */
84void _thread_tag_lock(void **);
85void _thread_tag_unlock(void **);
86void *_thread_tag_storage(void **, void *, size_t, void *);
87void _thread_mutex_lock(void **);
88void _thread_mutex_unlock(void **);
89void _thread_mutex_destroy(void **);
90
91/*
92 * Macros used in libc to access thread mutex, keys, and per thread storage.
93 * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for
94 * historical reasons. They do the same thing, define a static variable
95 * keyed by 'name' that identifies a mutex and a key to identify per thread
96 * data.
97 */
98#define _THREAD_PRIVATE_KEY(name) \
99 static void *__THREAD_NAME(name)
100#define _THREAD_PRIVATE_MUTEX(name) \
101 static void *__THREAD_NAME(name)
102#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
103 _thread_tag_lock(&(__THREAD_NAME(name)))
104#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
105 _thread_tag_unlock(&(__THREAD_NAME(name)))
106#define _THREAD_PRIVATE(keyname, storage, error) \
107 _thread_tag_storage(&(__THREAD_NAME(keyname)), &(storage), \
108 sizeof (storage), error)
109
110/*
111 * Macros used in libc to access mutexes.
112 */
113#define _MUTEX_LOCK(mutex) \
114 do { \
115 if (__isthreaded) \
116 _thread_mutex_lock(mutex); \
117 } while (0)
118#define _MUTEX_UNLOCK(mutex) \
119 do { \
120 if (__isthreaded) \
121 _thread_mutex_unlock(mutex); \
122 } while (0)
123#define _MUTEX_DESTROY(mutex) \
124 do { \
125 if (__isthreaded) \
126 _thread_mutex_destroy(mutex); \
127 } while (0)
128
129/*
130 * Resolver code is special cased in that it uses global keys.
131 */
132extern void *__THREAD_NAME(_res);
133extern void *__THREAD_NAME(_res_ext);
134extern void *__THREAD_NAME(serv_mutex);
135
136/*
137 * malloc lock/unlock prototypes and definitions
138 */
139void _thread_malloc_lock(void);
140void _thread_malloc_unlock(void);
141
142#define _MALLOC_LOCK() do { \
143 if (__isthreaded) \
144 _thread_malloc_lock(); \
145 } while (0)
146#define _MALLOC_UNLOCK() do { \
147 if (__isthreaded) \
148 _thread_malloc_unlock();\
149 } while (0)
150
151void _thread_atexit_lock(void);
152void _thread_atexit_unlock(void);
153
154#define _ATEXIT_LOCK() do { \
155 if (__isthreaded) \
156 _thread_atexit_lock(); \
157 } while (0)
158#define _ATEXIT_UNLOCK() do { \
159 if (__isthreaded) \
160 _thread_atexit_unlock();\
161 } while (0)
162
163void _thread_arc4_lock(void);
164void _thread_arc4_unlock(void);
165
166#define _ARC4_LOCK() do { \
167 if (__isthreaded) \
168 _thread_arc4_lock(); \
169 } while (0)
170#define _ARC4_UNLOCK() do { \
171 if (__isthreaded) \
172 _thread_arc4_unlock();\
173 } while (0)
174
175#endif /* _THREAD_PRIVATE_H_ */
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
new file mode 100644
index 0000000000..f4153bbfb4
--- /dev/null
+++ b/src/lib/libc/net/Makefile.inc
@@ -0,0 +1,98 @@
1# $OpenBSD: Makefile.inc,v 1.51 2014/04/07 17:57:56 schwarze Exp $
2
3# net sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/net ${LIBCSRCDIR}/net
5
6CFLAGS+=-DRESOLVSORT
7
8SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
9 getifaddrs.c getnameinfo.c getnetbyaddr.c getnetbyname.c getnetent.c \
10 getnetnamadr.c getpeereid.c getproto.c getprotoent.c getprotoname.c \
11 getservbyname.c getservbyport.c getservent.c getrrsetbyname.c \
12 herror.c if_indextoname.c if_nameindex.c if_nametoindex.c inet_addr.c \
13 inet_lnaof.c inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
14 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c inet_pton.c \
15 linkaddr.c rcmd.c ruserok.c rresvport.c recv.c res_comp.c res_data.c \
16 res_debug.c res_debug_syms.c res_init.c res_mkquery.c res_query.c \
17 res_random.c res_send.c send.c sethostent.c ethers.c rcmdsh.c
18
19# IPv6
20SRCS+= ip6opt.c rthdr.c vars6.c
21
22# machine-dependent net sources
23# m-d Makefile.inc must include sources for:
24# htonl() htons() ntohl() ntohs()
25
26.include "${LIBCSRCDIR}/arch/${MACHINE_CPU}/net/Makefile.inc"
27
28MAN+= byteorder.3 ethers.3 gai_strerror.3 getaddrinfo.3 gethostbyname.3 \
29 getifaddrs.3 getnameinfo.3 getnetent.3 getpeereid.3 getprotoent.3 \
30 getrrsetbyname.3 getservent.3 if_indextoname.3 inet.3 \
31 inet_net.3 inet6_option_space.3 inet6_rthdr_space.3 \
32 inet6_opt_init.3 inet6_rth_space.3 link_addr.3 \
33 rcmd.3 rcmdsh.3 resolver.3
34
35MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
36 byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \
37 byteorder.3 htobe64.3 byteorder.3 betoh16.3 byteorder.3 betoh32.3 \
38 byteorder.3 betoh64.3 byteorder.3 htole16.3 byteorder.3 htole32.3 \
39 byteorder.3 htole64.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \
40 byteorder.3 letoh64.3 byteorder.3 swap16.3 byteorder.3 swap32.3 \
41 byteorder.3 swap64.3
42MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
43 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3
44MLINKS+=getaddrinfo.3 freeaddrinfo.3
45MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
46 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
47 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \
48 gethostbyname.3 hstrerror.3
49MLINKS+=getifaddrs.3 freeifaddrs.3
50MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
51 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
52MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
53 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 \
54 getprotoent.3 getprotoent_r.3 getprotoent.3 getprotobyname_r.3 \
55 getprotoent.3 getprotobynumber_r.3 getprotoent.3 setprotoent_r.3 \
56 getprotoent.3 endprotoent_r.3
57MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
58 getservent.3 getservbyport.3 getservent.3 setservent.3 \
59 getservent.3 getservent_r.3 getservent.3 getservbyname_r.3 \
60 getservent.3 getservbyport_r.3 getservent.3 setservent_r.3 \
61 getservent.3 endservent_r.3
62MLINKS+= if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
63 if_indextoname.3 if_freenameindex.3
64MLINKS+=inet.3 inet_addr.3 inet.3 inet_aton.3 \
65 inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \
66 inet.3 inet_network.3 inet.3 inet_ntoa.3 \
67 inet.3 inet_ntop.3 inet.3 inet_pton.3
68MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3
69MLINKS+=link_addr.3 link_ntoa.3
70MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 \
71 rcmd.3 rresvport_af.3 rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3
72MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
73 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
74 resolver.3 res_search.3
75MLINKS+=getrrsetbyname.3 freerrset.3
76MLINKS+=inet6_option_space.3 inet6_option_init.3 \
77 inet6_option_space.3 inet6_option_append.3 \
78 inet6_option_space.3 inet6_option_alloc.3 \
79 inet6_option_space.3 inet6_option_next.3 \
80 inet6_option_space.3 inet6_option_find.3
81MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \
82 inet6_rthdr_space.3 inet6_rthdr_add.3 \
83 inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \
84 inet6_rthdr_space.3 inet6_rthdr_reverse.3 \
85 inet6_rthdr_space.3 inet6_rthdr_segments.3 \
86 inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
87 inet6_rthdr_space.3 inet6_rthdr_getflags.3
88MLINKS+=inet6_opt_init.3 inet6_opt_append.3 \
89 inet6_opt_init.3 inet6_opt_finish.3 \
90 inet6_opt_init.3 inet6_opt_set_val.3 \
91 inet6_opt_init.3 inet6_opt_next.3 \
92 inet6_opt_init.3 inet6_opt_find.3 \
93 inet6_opt_init.3 inet6_opt_get_val.3
94MLINKS+=inet6_rth_space.3 inet6_rth_init.3 \
95 inet6_rth_space.3 inet6_rth_add.3 \
96 inet6_rth_space.3 inet6_rth_reverse.3 \
97 inet6_rth_space.3 inet6_rth_segments.3 \
98 inet6_rth_space.3 inet6_rth_getaddr.3 \
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c
new file mode 100644
index 0000000000..7c3d1d319f
--- /dev/null
+++ b/src/lib/libc/net/base64.c
@@ -0,0 +1,316 @@
1/* $OpenBSD: base64.c,v 1.7 2013/12/31 02:32:56 tedu Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/socket.h>
48#include <netinet/in.h>
49#include <arpa/inet.h>
50#include <arpa/nameser.h>
51
52#include <ctype.h>
53#include <resolv.h>
54#include <stdio.h>
55
56#include <stdlib.h>
57#include <string.h>
58
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 u_char nextbyte;
198 char *pos;
199
200 state = 0;
201 tarindex = 0;
202
203 while ((ch = (unsigned char)*src++) != '\0') {
204 if (isspace(ch)) /* Skip whitespace anywhere. */
205 continue;
206
207 if (ch == Pad64)
208 break;
209
210 pos = strchr(Base64, ch);
211 if (pos == 0) /* A non-base64 character. */
212 return (-1);
213
214 switch (state) {
215 case 0:
216 if (target) {
217 if (tarindex >= targsize)
218 return (-1);
219 target[tarindex] = (pos - Base64) << 2;
220 }
221 state = 1;
222 break;
223 case 1:
224 if (target) {
225 if (tarindex >= targsize)
226 return (-1);
227 target[tarindex] |= (pos - Base64) >> 4;
228 nextbyte = ((pos - Base64) & 0x0f) << 4;
229 if (tarindex + 1 < targsize)
230 target[tarindex+1] = nextbyte;
231 else if (nextbyte)
232 return (-1);
233 }
234 tarindex++;
235 state = 2;
236 break;
237 case 2:
238 if (target) {
239 if (tarindex >= targsize)
240 return (-1);
241 target[tarindex] |= (pos - Base64) >> 2;
242 nextbyte = ((pos - Base64) & 0x03) << 6;
243 if (tarindex + 1 < targsize)
244 target[tarindex+1] = nextbyte;
245 else if (nextbyte)
246 return (-1);
247 }
248 tarindex++;
249 state = 3;
250 break;
251 case 3:
252 if (target) {
253 if (tarindex >= targsize)
254 return (-1);
255 target[tarindex] |= (pos - Base64);
256 }
257 tarindex++;
258 state = 0;
259 break;
260 }
261 }
262
263 /*
264 * We are done decoding Base-64 chars. Let's see if we ended
265 * on a byte boundary, and/or with erroneous trailing characters.
266 */
267
268 if (ch == Pad64) { /* We got a pad char. */
269 ch = (unsigned char)*src++; /* Skip it, get next. */
270 switch (state) {
271 case 0: /* Invalid = in first position */
272 case 1: /* Invalid = in second position */
273 return (-1);
274
275 case 2: /* Valid, means one byte of info */
276 /* Skip any number of spaces. */
277 for (; ch != '\0'; ch = (unsigned char)*src++)
278 if (!isspace(ch))
279 break;
280 /* Make sure there is another trailing = sign. */
281 if (ch != Pad64)
282 return (-1);
283 ch = (unsigned char)*src++; /* Skip the = */
284 /* Fall through to "single trailing =" case. */
285 /* FALLTHROUGH */
286
287 case 3: /* Valid, means two bytes of info */
288 /*
289 * We know this char is an =. Is there anything but
290 * whitespace after it?
291 */
292 for (; ch != '\0'; ch = (unsigned char)*src++)
293 if (!isspace(ch))
294 return (-1);
295
296 /*
297 * Now make sure for cases 2 and 3 that the "extra"
298 * bits that slopped past the last full byte were
299 * zeros. If we don't check them, they become a
300 * subliminal channel.
301 */
302 if (target && tarindex < targsize &&
303 target[tarindex] != 0)
304 return (-1);
305 }
306 } else {
307 /*
308 * We ended by seeing the end of the string. Make sure we
309 * have no partial bytes lying around.
310 */
311 if (state != 0)
312 return (-1);
313 }
314
315 return (tarindex);
316}
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3
new file mode 100644
index 0000000000..53f9fd071d
--- /dev/null
+++ b/src/lib/libc/net/byteorder.3
@@ -0,0 +1,206 @@
1.\" $OpenBSD: byteorder.3,v 1.18 2013/06/05 03:39:22 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt BYTEORDER 3
32.Os
33.Sh NAME
34.Nm htonl ,
35.Nm htons ,
36.Nm ntohl ,
37.Nm ntohs ,
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
54.Sh SYNOPSIS
55.In sys/types.h
56.Ft u_int32_t
57.Fn htonl "u_int32_t host32"
58.Ft u_int16_t
59.Fn htons "u_int16_t host16"
60.Ft u_int32_t
61.Fn ntohl "u_int32_t net32"
62.Ft u_int16_t
63.Fn ntohs "u_int16_t net16"
64.Ft u_int64_t
65.Fn htobe64 "u_int64_t host64"
66.Ft u_int32_t
67.Fn htobe32 "u_int32_t host32"
68.Ft u_int16_t
69.Fn htobe16 "u_int16_t host16"
70.Ft u_int64_t
71.Fn betoh64 "u_int64_t big64"
72.Ft u_int32_t
73.Fn betoh32 "u_int32_t big32"
74.Ft u_int16_t
75.Fn betoh16 "u_int16_t big16"
76.Ft u_int64_t
77.Fn htole64 "u_int64_t host64"
78.Ft u_int32_t
79.Fn htole32 "u_int32_t host32"
80.Ft u_int16_t
81.Fn htole16 "u_int16_t host16"
82.Ft u_int64_t
83.Fn letoh64 "u_int64_t little64"
84.Ft u_int32_t
85.Fn letoh32 "u_int32_t little32"
86.Ft u_int16_t
87.Fn letoh16 "u_int16_t little16"
88.Ft u_int64_t
89.Fn swap64 "u_int64_t val64"
90.Ft u_int32_t
91.Fn swap32 "u_int32_t val32"
92.Ft u_int16_t
93.Fn swap16 "u_int16_t val16"
94.Sh DESCRIPTION
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
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.
159On machines which have a byte order which is the same as the network
160order, routines are defined as null macros.
161.Pp
162The functions involving either
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
181.Xr gethostbyname 3
182and
183.Xr getservent 3 .
184.Sh SEE ALSO
185.Xr gethostbyname 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.
198.Sh HISTORY
199The
200.Nm byteorder
201functions appeared in
202.Bx 4.2 .
203.Sh BUGS
204On the vax, alpha, amd64, i386, and some mips and arm architectures,
205bytes are handled backwards from most everyone else in the world.
206This is not expected to be fixed in the near future.
diff --git a/src/lib/libc/net/ethers.3 b/src/lib/libc/net/ethers.3
new file mode 100644
index 0000000000..c254a120a7
--- /dev/null
+++ b/src/lib/libc/net/ethers.3
@@ -0,0 +1,124 @@
1.\" $OpenBSD: ethers.3,v 1.23 2014/03/18 03:58:49 lteo Exp $
2.\"
3.\" Written by roland@frob.com. Public domain.
4.\"
5.Dd $Mdocdate: March 18 2014 $
6.Dt ETHERS 3
7.Os
8.Sh NAME
9.Nm ether_aton ,
10.Nm ether_ntoa ,
11.Nm ether_ntohost ,
12.Nm ether_hostton ,
13.Nm ether_line
14.Nd get ethers entry
15.Sh SYNOPSIS
16.In sys/types.h
17.In sys/socket.h
18.In net/if.h
19.In netinet/in.h
20.In netinet/if_ether.h
21.Ft char *
22.Fn ether_ntoa "struct ether_addr *e"
23.Ft struct ether_addr *
24.Fn ether_aton "const char *s"
25.Ft int
26.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
27.Ft int
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"
31.Sh DESCRIPTION
32Ethernet addresses are represented by the
33following structure:
34.Bd -literal -offset indent
35struct ether_addr {
36 u_int8_t ether_addr_octet[ETHER_ADDR_LEN];
37};
38.Ed
39.Pp
40The
41.Fn ether_ntoa
42function converts this structure into an
43.Tn ASCII
44string of the form
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.
49The
50.Fn ether_aton
51converts an
52.Tn ASCII
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.
56.Fn ether_aton
57will return NULL if the string does not represent a valid address.
58.Pp
59The
60.Fn ether_ntohost
61and
62.Fn ether_hostton
63functions interrogate the database mapping host names to Ethernet
64addresses,
65.Pa /etc/ethers .
66The
67.Fn ether_ntohost
68function looks up the given Ethernet address and writes the associated
69host name into the character buffer passed.
70This buffer should be
71.Dv MAXHOSTNAMELEN
72characters in size.
73The
74.Fn ether_hostton
75function looks up the given host name and writes the associated
76Ethernet address into the structure passed.
77Both functions return
78zero if they find the requested host name or address, and \-1 if not.
79.Pp
80Each call reads
81.Pa /etc/ethers
82from the beginning; if a
83.Ql +
84appears alone on a line in the file, then
85.Fn ether_hostton
86will consult the
87.Pa ethers.byname
88YP map, and
89.Fn ether_ntohost
90will consult the
91.Pa ethers.byaddr
92YP map.
93.Pp
94The
95.Fn ether_line
96function parses a line from the
97.Pa /etc/ethers
98file and fills in the passed
99.Li struct ether_addr
100and character buffer with the Ethernet address and host name on the line.
101It returns zero if the line was successfully parsed and \-1 if not.
102The character buffer should be
103.Dv MAXHOSTNAMELEN
104characters in size.
105.Sh FILES
106.Bl -tag -width /etc/ethers -compact
107.It Pa /etc/ethers
108.El
109.Sh SEE ALSO
110.Xr ethers 5
111.Sh HISTORY
112The
113.Fn ether_ntoa ,
114.Fn ether_aton ,
115.Fn ether_ntohost ,
116.Fn ether_hostton ,
117and
118.Fn ether_line
119functions were adopted from SunOS and appeared in
120.Nx 0.9b .
121.Sh BUGS
122The data space used by these functions is static; if future use
123requires the data, it should be copied before any subsequent calls to
124these functions overwrite it.
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c
new file mode 100644
index 0000000000..af31bb8e60
--- /dev/null
+++ b/src/lib/libc/net/ethers.c
@@ -0,0 +1,234 @@
1/* $OpenBSD: ethers.c,v 1.21 2013/11/24 23:51:28 deraadt 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/*
20 * ethers(3) a la Sun.
21 * Originally Written by Roland McGrath <roland@frob.com> 10/14/93.
22 * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com>
23 */
24
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <net/if.h>
28#include <netinet/in.h>
29#include <netinet/if_ether.h>
30#include <sys/param.h>
31#include <paths.h>
32#include <errno.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <ctype.h>
37#ifdef YP
38#include <rpcsvc/ypclnt.h>
39#endif
40
41#ifndef _PATH_ETHERS
42#define _PATH_ETHERS "/etc/ethers"
43#endif
44
45static char * _ether_aton(const char *, struct ether_addr *);
46
47char *
48ether_ntoa(struct ether_addr *e)
49{
50 static char a[] = "xx:xx:xx:xx:xx:xx";
51
52 (void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
53 e->ether_addr_octet[0], e->ether_addr_octet[1],
54 e->ether_addr_octet[2], e->ether_addr_octet[3],
55 e->ether_addr_octet[4], e->ether_addr_octet[5]);
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((unsigned char)*s))
68 s++;
69
70 /* expect 6 hex octets separated by ':' or space/NUL if last octet */
71 for (i = 0; i < 6; i++) {
72 l = strtol(s, &pp, 16);
73 if (pp == s || l > 0xFF || l < 0)
74 return (NULL);
75 if (!(*pp == ':' ||
76 (i == 5 && (isspace((unsigned char)*pp) ||
77 *pp == '\0'))))
78 return (NULL);
79 e->ether_addr_octet[i] = (u_char)l;
80 s = pp + 1;
81 }
82
83 /* return character after the octets ala strtol(3) */
84 return (pp);
85}
86
87struct ether_addr *
88ether_aton(const char *s)
89{
90 static struct ether_addr n;
91
92 return (_ether_aton(s, &n) ? &n : NULL);
93}
94
95int
96ether_ntohost(char *hostname, struct ether_addr *e)
97{
98 FILE *f;
99 char buf[BUFSIZ+1], *p;
100 size_t len;
101 struct ether_addr try;
102#ifdef YP
103 char trybuf[sizeof("xx:xx:xx:xx:xx:xx")];
104 int trylen;
105#endif
106
107#ifdef YP
108 snprintf(trybuf, sizeof trybuf, "%x:%x:%x:%x:%x:%x",
109 e->ether_addr_octet[0], e->ether_addr_octet[1],
110 e->ether_addr_octet[2], e->ether_addr_octet[3],
111 e->ether_addr_octet[4], e->ether_addr_octet[5]);
112 trylen = strlen(trybuf);
113#endif
114
115 f = fopen(_PATH_ETHERS, "r");
116 if (f == NULL)
117 return (-1);
118 while ((p = fgetln(f, &len)) != NULL) {
119 if (p[len-1] == '\n')
120 len--;
121 if (len > sizeof(buf) - 2)
122 continue;
123 (void)memcpy(buf, p, len);
124 buf[len] = '\n'; /* code assumes newlines later on */
125 buf[len+1] = '\0';
126#ifdef YP
127 /* A + in the file means try YP now. */
128 if (!strncmp(buf, "+\n", sizeof(buf))) {
129 char *ypbuf, *ypdom;
130 int ypbuflen;
131
132 if (yp_get_default_domain(&ypdom))
133 continue;
134 if (yp_match(ypdom, "ethers.byaddr", trybuf,
135 trylen, &ypbuf, &ypbuflen))
136 continue;
137 if (ether_line(ypbuf, &try, hostname) == 0) {
138 free(ypbuf);
139 (void)fclose(f);
140 return (0);
141 }
142 free(ypbuf);
143 continue;
144 }
145#endif
146 if (ether_line(buf, &try, hostname) == 0 &&
147 memcmp((void *)&try, (void *)e, sizeof(try)) == 0) {
148 (void)fclose(f);
149 return (0);
150 }
151 }
152 (void)fclose(f);
153 errno = ENOENT;
154 return (-1);
155}
156
157int
158ether_hostton(const char *hostname, struct ether_addr *e)
159{
160 FILE *f;
161 char buf[BUFSIZ+1], *p;
162 char try[MAXHOSTNAMELEN];
163 size_t len;
164#ifdef YP
165 int hostlen = strlen(hostname);
166#endif
167
168 f = fopen(_PATH_ETHERS, "r");
169 if (f==NULL)
170 return (-1);
171
172 while ((p = fgetln(f, &len)) != NULL) {
173 if (p[len-1] == '\n')
174 len--;
175 if (len > sizeof(buf) - 2)
176 continue;
177 memcpy(buf, p, len);
178 buf[len] = '\n'; /* code assumes newlines later on */
179 buf[len+1] = '\0';
180#ifdef YP
181 /* A + in the file means try YP now. */
182 if (!strncmp(buf, "+\n", sizeof(buf))) {
183 char *ypbuf, *ypdom;
184 int ypbuflen;
185
186 if (yp_get_default_domain(&ypdom))
187 continue;
188 if (yp_match(ypdom, "ethers.byname", hostname, hostlen,
189 &ypbuf, &ypbuflen))
190 continue;
191 if (ether_line(ypbuf, e, try) == 0) {
192 free(ypbuf);
193 (void)fclose(f);
194 return (0);
195 }
196 free(ypbuf);
197 continue;
198 }
199#endif
200 if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) {
201 (void)fclose(f);
202 return (0);
203 }
204 }
205 (void)fclose(f);
206 errno = ENOENT;
207 return (-1);
208}
209
210int
211ether_line(const char *line, struct ether_addr *e, char *hostname)
212{
213 char *p;
214 size_t n;
215
216 /* Parse "xx:xx:xx:xx:xx:xx" */
217 if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t'))
218 goto bad;
219
220 /* Now get the hostname */
221 while (isspace((unsigned char)*p))
222 p++;
223 if (*p == '\0')
224 goto bad;
225 n = strcspn(p, " \t\n");
226 if (n >= MAXHOSTNAMELEN)
227 goto bad;
228 strlcpy(hostname, p, n + 1);
229 return (0);
230
231bad:
232 errno = EINVAL;
233 return (-1);
234}
diff --git a/src/lib/libc/net/freeaddrinfo.c b/src/lib/libc/net/freeaddrinfo.c
new file mode 100644
index 0000000000..58702d0b18
--- /dev/null
+++ b/src/lib/libc/net/freeaddrinfo.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: freeaddrinfo.c,v 1.6 2005/03/25 13:24:11 otto Exp $ */
2
3/*
4 * Copyright (c) 1996, 1997, 1998, 1999, Craig Metz, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Craig Metz and
17 * by other contributors.
18 * 4. Neither the name of the author nor the names of contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <stdlib.h>
36#include <netdb.h>
37
38void
39freeaddrinfo(struct addrinfo *ai)
40{
41 struct addrinfo *p;
42
43 do {
44 p = ai;
45 ai = ai->ai_next;
46 if (p->ai_canonname)
47 free(p->ai_canonname);
48 free((void *)p);
49 } while (ai);
50}
diff --git a/src/lib/libc/net/gai_strerror.3 b/src/lib/libc/net/gai_strerror.3
new file mode 100644
index 0000000000..e0373eb91e
--- /dev/null
+++ b/src/lib/libc/net/gai_strerror.3
@@ -0,0 +1,95 @@
1.\" $OpenBSD: gai_strerror.3,v 1.9 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: gai_strerror.3,v 1.1 2005/01/05 03:04:47 itojun Exp $
3.\"
4.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
5.\" Copyright (C) 2000, 2001 Internet Software Consortium.
6.\"
7.\" Permission to use, copy, modify, and distribute this software for any
8.\" purpose with or without fee is hereby granted, provided that the above
9.\" copyright notice and this permission notice appear in all copies.
10.\"
11.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17.\" PERFORMANCE OF THIS SOFTWARE.
18.\"
19.Dd $Mdocdate: January 21 2014 $
20.Dt GAI_STRERROR 3
21.Os
22.Sh NAME
23.Nm gai_strerror
24.Nd get error message string from EAI_xxx error code
25.Sh SYNOPSIS
26.In sys/types.h
27.In sys/socket.h
28.In netdb.h
29.Ft "const char *"
30.Fn gai_strerror "int ecode"
31.Sh DESCRIPTION
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.In 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_OVERFLOW
72argument buffer overflow
73.It Dv EAI_PROTOCOL
74resolved protocol is unknown
75.It Dv EAI_SERVICE
76.Fa servname
77not supported for
78.Fa ai_socktype
79.It Dv EAI_SOCKTYPE
80.Fa ai_socktype
81not supported
82.It Dv EAI_SYSTEM
83system error returned in
84.Va errno
85.El
86.Sh RETURN VALUES
87.Fn gai_strerror
88returns a pointer to the error message string corresponding to
89.Fa ecode .
90If
91.Fa ecode
92is out of range, an implementation-specific error message string is returned.
93.Sh SEE ALSO
94.Xr getaddrinfo 3 ,
95.Xr getnameinfo 3
diff --git a/src/lib/libc/net/gai_strerror.c b/src/lib/libc/net/gai_strerror.c
new file mode 100644
index 0000000000..f4126413f8
--- /dev/null
+++ b/src/lib/libc/net/gai_strerror.c
@@ -0,0 +1,78 @@
1/* $OpenBSD: gai_strerror.c,v 1.7 2009/06/02 16:47:50 jasper Exp $ */
2
3/*
4 * Copyright (c) 1997-1999, Craig Metz, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Craig Metz and
17 * by other contributors.
18 * 4. Neither the name of the author nor the names of contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/* gai_strerror() v1.38 */
36
37#include <sys/types.h>
38#include <netdb.h>
39#include <errno.h>
40
41const char *
42gai_strerror(int errnum)
43{
44 switch (errnum) {
45 case 0:
46 return "no error";
47 case EAI_BADFLAGS:
48 return "invalid value for ai_flags";
49 case EAI_NONAME:
50 return "name or service is not known";
51 case EAI_AGAIN:
52 return "temporary failure in name resolution";
53 case EAI_FAIL:
54 return "non-recoverable failure in name resolution";
55 case EAI_NODATA:
56 return "no address associated with name";
57 case EAI_FAMILY:
58 return "ai_family not supported";
59 case EAI_SOCKTYPE:
60 return "ai_socktype not supported";
61 case EAI_SERVICE:
62 return "service not supported for ai_socktype";
63 case EAI_ADDRFAMILY:
64 return "address family for name not supported";
65 case EAI_MEMORY:
66 return "memory allocation failure";
67 case EAI_SYSTEM:
68 return "system error";
69 case EAI_BADHINTS:
70 return "invalid value for hints";
71 case EAI_PROTOCOL:
72 return "resolved protocol is unknown";
73 case EAI_OVERFLOW:
74 return "argument buffer overflow";
75 default:
76 return "unknown/invalid error";
77 }
78}
diff --git a/src/lib/libc/net/getaddrinfo.3 b/src/lib/libc/net/getaddrinfo.3
new file mode 100644
index 0000000000..db4417ab35
--- /dev/null
+++ b/src/lib/libc/net/getaddrinfo.3
@@ -0,0 +1,465 @@
1.\" $OpenBSD: getaddrinfo.3,v 1.54 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: getaddrinfo.3,v 1.36 2005/01/05 03:23:05 itojun Exp $
3.\"
4.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
5.\" Copyright (C) 2000, 2001 Internet Software Consortium.
6.\"
7.\" Permission to use, copy, modify, and distribute this software for any
8.\" purpose with or without fee is hereby granted, provided that the above
9.\" copyright notice and this permission notice appear in all copies.
10.\"
11.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17.\" PERFORMANCE OF THIS SOFTWARE.
18.\"
19.Dd $Mdocdate: January 21 2014 $
20.Dt GETADDRINFO 3
21.Os
22.Sh NAME
23.Nm getaddrinfo ,
24.Nm freeaddrinfo
25.Nd host and service name to socket address structure
26.Sh SYNOPSIS
27.In sys/types.h
28.In sys/socket.h
29.In netdb.h
30.Ft int
31.Fn getaddrinfo "const char *hostname" "const char *servname" \
32 "const struct addrinfo *hints" "struct addrinfo **res"
33.Ft void
34.Fn freeaddrinfo "struct addrinfo *ai"
35.Sh DESCRIPTION
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.In 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 host name in the
130.Fa ai_canonname
131element of the first
132.Li addrinfo
133structure returned.
134.It Dv AI_FQDN
135If the
136.Dv AI_FQDN
137bit is set, a successful call to
138.Fn getaddrinfo
139will return a NUL-terminated string containing the fully qualified domain name
140of the specified host name in the
141.Fa ai_canonname
142element of the first
143.Li addrinfo
144structure returned.
145.Pp
146This is different from the
147.Dv AI_CANONNAME
148bit flag that returns the canonical name registered in DNS,
149which may be different from the fully qualified domain name
150that the host name resolved to.
151Only one of the
152.Dv AI_FQDN
153and
154.Dv AI_CANONNAME
155bits can be set.
156.It Dv AI_NUMERICHOST
157If the
158.Dv AI_NUMERICHOST
159bit is set, it indicates that
160.Fa hostname
161should be treated as a numeric string defining an IPv4 or IPv6 address
162and no name resolution should be attempted.
163.It Dv AI_NUMERICSERV
164If the
165.Dv AI_NUMERICSERV
166bit is set, it indicates that
167.Fa servname
168should be treated as a numeric port string
169and no service name resolution should be attempted.
170.It Dv AI_PASSIVE
171If the
172.Dv AI_PASSIVE
173bit is set it indicates that the returned socket address structure
174is intended for use in a call to
175.Xr bind 2 .
176In this case, if the
177.Fa hostname
178argument is the null pointer, then the IP address portion of the
179socket address structure will be set to
180.Dv INADDR_ANY
181for an IPv4 address or
182.Dv IN6ADDR_ANY_INIT
183for an IPv6 address.
184.Pp
185If the
186.Dv AI_PASSIVE
187bit is not set, the returned socket address structure will be ready
188for use in a call to
189.Xr connect 2
190for a connection-oriented protocol or
191.Xr connect 2 ,
192.Xr sendto 2 ,
193or
194.Xr sendmsg 2
195if a connectionless protocol was chosen.
196The
197.Tn IP
198address portion of the socket address structure will be set to the
199loopback address if
200.Fa hostname
201is the null pointer and
202.Dv AI_PASSIVE
203is not set.
204.El
205.El
206.Pp
207All other elements of the
208.Li addrinfo
209structure passed via
210.Fa hints
211must be zero or the null pointer.
212.Pp
213If
214.Fa hints
215is the null pointer,
216.Fn getaddrinfo
217behaves as if the caller provided a
218.Li struct addrinfo
219with
220.Fa ai_family
221set to
222.Dv PF_UNSPEC
223and all other elements set to zero or
224.Dv NULL .
225.Pp
226After a successful call to
227.Fn getaddrinfo ,
228.Fa *res
229is a pointer to a linked list of one or more
230.Li addrinfo
231structures.
232The list can be traversed by following the
233.Fa ai_next
234pointer in each
235.Li addrinfo
236structure until a null pointer is encountered.
237The three members
238.Fa ai_family ,
239.Fa ai_socktype ,
240and
241.Fa ai_protocol
242in each returned
243.Li addrinfo
244structure are suitable for a call to
245.Xr socket 2 .
246For each
247.Li addrinfo
248structure in the list, the
249.Fa ai_addr
250member points to a filled-in socket address structure of length
251.Fa ai_addrlen .
252.Pp
253This implementation of
254.Fn getaddrinfo
255allows numeric IPv6 address notation with scope identifier,
256as documented in RFC 4007.
257By appending the percent character and scope identifier to addresses,
258one can fill the
259.Li sin6_scope_id
260field for addresses.
261This would make management of scoped addresses easier
262and allows cut-and-paste input of scoped addresses.
263.Pp
264At this moment the code supports only link-local addresses with the format.
265The scope identifier is hardcoded to the name of the hardware interface
266associated
267with the link
268.Po
269such as
270.Li ne0
271.Pc .
272An example is
273.Dq Li fe80::1%ne0 ,
274which means
275.Do
276.Li fe80::1
277on the link associated with the
278.Li ne0
279interface
280.Dc .
281.Pp
282The current implementation assumes a one-to-one relationship between
283the interface and link, which is not necessarily true from the specification.
284.Pp
285All of the information returned by
286.Fn getaddrinfo
287is dynamically allocated: the
288.Li addrinfo
289structures themselves as well as the socket address structures and
290the canonical host name strings included in the
291.Li addrinfo
292structures.
293.Pp
294Memory allocated for the dynamically allocated structures created by
295a successful call to
296.Fn getaddrinfo
297is released by the
298.Fn freeaddrinfo
299function.
300The
301.Fa ai
302pointer should be an
303.Li addrinfo
304structure created by a call to
305.Fn getaddrinfo .
306.Sh RETURN VALUES
307.Fn getaddrinfo
308returns zero on success or one of the error codes listed in
309.Xr gai_strerror 3
310if an error occurs.
311If an error occurs, no memory is allocated by
312.Fn getaddrinfo ,
313therefore it is not necessary to release the
314.Li addrinfo
315structure(s).
316.Sh EXAMPLES
317The following code tries to connect to
318.Dq Li www.kame.net
319service
320.Dq Li www
321via a stream socket.
322It loops through all the addresses available, regardless of address family.
323If the destination resolves to an IPv4 address, it will use an
324.Dv AF_INET
325socket.
326Similarly, if it resolves to IPv6, an
327.Dv AF_INET6
328socket is used.
329Observe that there is no hardcoded reference to a particular address family.
330The code works even if
331.Fn getaddrinfo
332returns addresses that are not IPv4/v6.
333.Bd -literal -offset indent
334struct addrinfo hints, *res, *res0;
335int error;
336int save_errno;
337int s;
338const char *cause = NULL;
339
340memset(&hints, 0, sizeof(hints));
341hints.ai_family = PF_UNSPEC;
342hints.ai_socktype = SOCK_STREAM;
343error = getaddrinfo("www.kame.net", "www", &hints, &res0);
344if (error)
345 errx(1, "%s", gai_strerror(error));
346s = -1;
347for (res = res0; res; res = res->ai_next) {
348 s = socket(res->ai_family, res->ai_socktype,
349 res->ai_protocol);
350 if (s == -1) {
351 cause = "socket";
352 continue;
353 }
354
355 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
356 cause = "connect";
357 save_errno = errno;
358 close(s);
359 errno = save_errno;
360 s = -1;
361 continue;
362 }
363
364 break; /* okay we got one */
365}
366if (s == -1)
367 err(1, "%s", cause);
368freeaddrinfo(res0);
369.Ed
370.Pp
371The following example tries to open a wildcard listening socket onto service
372.Dq Li www ,
373for all the address families available.
374.Bd -literal -offset indent
375struct addrinfo hints, *res, *res0;
376int error;
377int save_errno;
378int s[MAXSOCK];
379int nsock;
380const char *cause = NULL;
381
382memset(&hints, 0, sizeof(hints));
383hints.ai_family = PF_UNSPEC;
384hints.ai_socktype = SOCK_STREAM;
385hints.ai_flags = AI_PASSIVE;
386error = getaddrinfo(NULL, "www", &hints, &res0);
387if (error)
388 errx(1, "%s", gai_strerror(error));
389nsock = 0;
390for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
391 s[nsock] = socket(res->ai_family, res->ai_socktype,
392 res->ai_protocol);
393 if (s[nsock] == -1) {
394 cause = "socket";
395 continue;
396 }
397
398 if (bind(s[nsock], res->ai_addr, res->ai_addrlen) == -1) {
399 cause = "bind";
400 save_errno = errno;
401 close(s[nsock]);
402 errno = save_errno;
403 continue;
404 }
405 (void) listen(s[nsock], 5);
406
407 nsock++;
408}
409if (nsock == 0)
410 err(1, "%s", cause);
411freeaddrinfo(res0);
412.Ed
413.Sh SEE ALSO
414.Xr bind 2 ,
415.Xr connect 2 ,
416.Xr send 2 ,
417.Xr socket 2 ,
418.Xr gai_strerror 3 ,
419.Xr gethostbyname 3 ,
420.Xr getnameinfo 3 ,
421.Xr getservbyname 3 ,
422.Xr resolver 3 ,
423.Xr hosts 5 ,
424.Xr resolv.conf 5 ,
425.Xr services 5 ,
426.Xr hostname 7 ,
427.Xr named 8
428.Rs
429.%A Craig Metz
430.%B Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference
431.%D June 2000
432.%T Protocol Independence Using the Sockets API
433.Re
434.Sh STANDARDS
435The
436.Fn getaddrinfo
437function is defined by the
438.St -p1003.1g-2000
439draft specification and documented in RFC 3493.
440.Pp
441The
442.Dv AI_FQDN
443flag bit first appeared in Windows 7.
444.Pp
445.Rs
446.%A R. Gilligan
447.%A S. Thomson
448.%A J. Bound
449.%A J. McCann
450.%A W. Stevens
451.%D February 2003
452.%R RFC 3493
453.%T Basic Socket Interface Extensions for IPv6
454.Re
455.Pp
456.Rs
457.%A S. Deering
458.%A B. Haberman
459.%A T. Jinmei
460.%A E. Nordmark
461.%A B. Zill
462.%D March 2005
463.%R RFC 4007
464.%T IPv6 Scoped Address Architecture
465.Re
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
new file mode 100644
index 0000000000..206750a2c3
--- /dev/null
+++ b/src/lib/libc/net/gethostbyname.3
@@ -0,0 +1,297 @@
1.\" $OpenBSD: gethostbyname.3,v 1.26 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt GETHOSTBYNAME 3
32.Os
33.Sh NAME
34.Nm gethostbyname ,
35.Nm gethostbyname2 ,
36.Nm gethostbyaddr ,
37.Nm gethostent ,
38.Nm sethostent ,
39.Nm endhostent ,
40.Nm hstrerror ,
41.Nm herror
42.Nd get network host entry
43.Sh SYNOPSIS
44.In netdb.h
45.Vt extern int h_errno ;
46.Ft struct hostent *
47.Fn gethostbyname "const char *name"
48.Ft struct hostent *
49.Fn gethostbyname2 "const char *name" "int af"
50.Ft struct hostent *
51.Fn gethostbyaddr "const void *addr" "socklen_t len" "int af"
52.Ft struct hostent *
53.Fn gethostent void
54.Ft void
55.Fn sethostent "int stayopen"
56.Ft void
57.Fn endhostent void
58.Ft void
59.Fn herror "const char *string"
60.Ft const char *
61.Fn hstrerror "int err"
62.Sh DESCRIPTION
63The
64.Fn gethostbyname ,
65.Fn gethostbyname2 ,
66and
67.Fn gethostbyaddr
68functions each return a pointer to an object with the following structure
69describing an Internet host referenced by name or by address, respectively.
70This structure contains either information obtained from the name server (i.e.,
71.Xr resolver 3
72and
73.Xr named 8 ) ,
74broken-out fields from a line in
75.Pa /etc/hosts ,
76or database entries supplied by the
77.Xr yp 8
78system.
79.Xr resolv.conf 5
80describes how the particular database is chosen.
81.Bd -literal -offset indent
82struct hostent {
83 char *h_name; /* official name of host */
84 char **h_aliases; /* alias list */
85 int h_addrtype; /* host address type */
86 int h_length; /* length of address */
87 char **h_addr_list; /* list of returned addresses */
88};
89#define h_addr h_addr_list[0] /* address, for backward compat */
90.Ed
91.Pp
92The members of this structure are:
93.Bl -tag -width h_addr_list
94.It Fa h_name
95Official name of the host.
96.It Fa h_aliases
97A null-terminated array of alternate names for the host.
98.It Fa h_addrtype
99The type of address being returned.
100.It Fa h_length
101The length, in bytes, of the address.
102.It Fa h_addr_list
103A null-terminated array of network addresses for the host.
104Host addresses are returned in network byte order.
105.It Fa h_addr
106The first address in
107.Fa h_addr_list ;
108this is for backward compatibility.
109.El
110.Pp
111The function
112.Fn gethostbyname
113will search for the named host in the current domain and its parents
114using the search lookup semantics detailed in
115.Xr resolv.conf 5
116and
117.Xr hostname 7 .
118.Pp
119.Fn gethostbyname2
120is an advanced form of
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 .
137.Pp
138The
139.Fn sethostent
140function may be used to request the use of a connected
141.Tn TCP
142socket for queries.
143If the
144.Fa stayopen
145flag is non-zero,
146this sets the option to send all queries to the name server using
147.Tn TCP
148and to retain the connection after each call to
149.Fn gethostbyname
150or
151.Fn gethostbyaddr .
152Otherwise, queries are performed using
153.Tn UDP
154datagrams.
155.Pp
156The
157.Fn endhostent
158function closes the
159.Tn TCP
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
189.Sh FILES
190.Bl -tag -width /etc/resolv.conf -compact
191.It Pa /etc/hosts
192.It Pa /etc/resolv.conf
193.El
194.Sh DIAGNOSTICS
195Error return status from
196.Fn gethostbyname ,
197.Fn gethostbyname2 ,
198and
199.Fn gethostbyaddr
200is indicated by return of a null pointer.
201The external integer
202.Va h_errno
203may then be checked to see whether this is a temporary failure
204or an invalid or unknown host.
205.Pp
206The variable
207.Va h_errno
208can have the following values:
209.Bl -tag -width HOST_NOT_FOUND
210.It Dv HOST_NOT_FOUND
211No such host is known.
212.It Dv TRY_AGAIN
213This is usually a temporary error
214and means that the local server did not receive
215a response from an authoritative server.
216A retry at some later time may succeed.
217.It Dv NO_RECOVERY
218Some unexpected server failure was encountered.
219This is a non-recoverable error.
220.It Dv NO_DATA
221The requested name is valid but does not have an IP address;
222this is not a temporary error.
223This means that the name is known to the name server but there is no address
224associated with this name.
225Another type of request to the name server using this domain name
226will result in an answer;
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.
237.El
238.Sh SEE ALSO
239.Xr getaddrinfo 3 ,
240.Xr getnameinfo 3 ,
241.Xr resolver 3 ,
242.Xr hosts 5 ,
243.Xr resolv.conf 5 ,
244.Xr hostname 7 ,
245.Xr named 8
246.Sh HISTORY
247The
248.Fn herror
249function appeared in
250.Bx 4.3 .
251The
252.Fn endhostent ,
253.Fn gethostbyaddr ,
254.Fn gethostbyname ,
255.Fn gethostent ,
256and
257.Fn sethostent
258functions appeared in
259.Bx 4.2 .
260.Sh CAVEATS
261If the search routines in
262.Xr resolv.conf 5
263decide to read the
264.Pa /etc/hosts
265file,
266.Fn gethostent
267and other functions will
268read the next line of the file,
269re-opening the file if necessary.
270.Pp
271The
272.Fn sethostent
273function opens and/or rewinds the file
274.Pa /etc/hosts .
275If the
276.Fa stayopen
277argument is non-zero, the file will not be closed after each call to
278.Fn gethostbyname ,
279.Fn gethostbyname2 ,
280or
281.Fn gethostbyaddr .
282.Pp
283The
284.Fn endhostent
285function closes the file.
286.Sh BUGS
287These functions use static data storage;
288if the data is needed for future use, it should be
289copied before any subsequent calls overwrite it.
290.Pp
291Only the Internet
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/getifaddrs.3 b/src/lib/libc/net/getifaddrs.3
new file mode 100644
index 0000000000..0b3538302a
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.3
@@ -0,0 +1,160 @@
1.\" $OpenBSD: getifaddrs.3,v 1.19 2014/04/07 17:57:56 schwarze Exp $
2.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp
3.\"
4.\" Copyright (c) 1995, 1999
5.\" Berkeley Software Design, Inc. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.Dd $Mdocdate: April 7 2014 $
25.Dt GETIFADDRS 3
26.Os
27.Sh NAME
28.Nm getifaddrs ,
29.Nm freeifaddrs
30.Nd get interface addresses
31.Sh SYNOPSIS
32.In sys/types.h
33.In sys/socket.h
34.In ifaddrs.h
35.Ft int
36.Fn getifaddrs "struct ifaddrs **ifap"
37.Ft void
38.Fn freeifaddrs "struct ifaddrs *ifap"
39.Sh DESCRIPTION
40The
41.Fn getifaddrs
42function stores a reference to a linked list of the network interfaces
43on the local machine in the memory referenced by
44.Fa ifap .
45The list consists of
46.Nm ifaddrs
47structures, as defined in the include file
48.In ifaddrs.h .
49The
50.Nm ifaddrs
51structure contains at least the following entries:
52.Bd -literal
53 struct ifaddrs *ifa_next; /* Pointer to next struct */
54 char *ifa_name; /* Interface name */
55 u_int ifa_flags; /* Interface flags */
56 struct sockaddr *ifa_addr; /* Interface address */
57 struct sockaddr *ifa_netmask; /* Interface netmask */
58 struct sockaddr *ifa_broadaddr; /* Interface broadcast address */
59 struct sockaddr *ifa_dstaddr; /* P2P interface destination */
60 void *ifa_data; /* Address specific data */
61.Ed
62.Bl -tag -width ifa_broadaddr
63.It Fa ifa_next
64Contains a pointer to the next structure on the list.
65This field is set to
66.Dv NULL
67in the last structure on the list.
68.It Fa ifa_name
69Contains the interface name.
70.It Fa ifa_flags
71Contains the interface flags, as set by
72.Xr ifconfig 8 .
73.It Fa ifa_addr
74References either the address of the interface or the link level
75address of the interface, if one exists, otherwise it is
76.Dv NULL .
77(The
78.Fa sa_family
79field of the
80.Fa ifa_addr
81field should be consulted to determine the format of the
82.Fa ifa_addr
83address.)
84.It Fa ifa_netmask
85References the netmask associated with
86.Fa ifa_addr ,
87if one is set, otherwise it is
88.Dv NULL .
89.It Fa ifa_broadaddr
90This field, which should only be referenced for non-P2P interfaces,
91references the broadcast address associated with
92.Fa ifa_addr ,
93if one exists, otherwise it is
94.Dv NULL .
95.It Fa ifa_dstaddr
96This field, which should only be referenced for P2P interfaces,
97references the destination address on a P2P interface,
98if one exists, otherwise it is
99.Dv NULL .
100.It Fa ifa_data
101References address family specific data.
102For
103.Dv AF_LINK
104addresses it contains a pointer to the
105.Li struct if_data
106(as defined in include file
107.In net/if.h )
108which contains various interface attributes and statistics.
109For all other address families,
110.Fa ifa_data
111is
112.Dv NULL .
113.El
114.Pp
115The data returned by
116.Fn getifaddrs
117is dynamically allocated and should be freed using
118.Fn freeifaddrs
119when no longer needed.
120.Sh RETURN VALUES
121Upon successful completion, a value of 0 is returned.
122Otherwise, a value of \-1 is returned and
123.Va errno
124is set to indicate the error.
125.Sh ERRORS
126The
127.Fn getifaddrs
128may fail and set
129.Va errno
130for any of the errors specified for the library routines
131.Xr ioctl 2 ,
132.Xr socket 2 ,
133.Xr malloc 3 ,
134or
135.Xr sysctl 3 .
136.Sh SEE ALSO
137.Xr ioctl 2 ,
138.Xr socket 2 ,
139.Xr sysctl 3 ,
140.Xr networking 4 ,
141.Xr ifconfig 8
142.Sh HISTORY
143The
144.Fn getifaddrs
145function first appeared in BSDI
146.Bsx .
147The function has been available on
148.Ox
149since
150.Ox 2.7 .
151.Sh BUGS
152If both
153.In net/if.h
154and
155.In ifaddrs.h
156are being included,
157.In net/if.h
158.Em must
159be included before
160.In ifaddrs.h .
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c
new file mode 100644
index 0000000000..da42a23783
--- /dev/null
+++ b/src/lib/libc/net/getifaddrs.c
@@ -0,0 +1,296 @@
1/* $OpenBSD: getifaddrs.c,v 1.11 2013/03/20 14:15:56 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1995, 1999
5 * Berkeley Software Design, Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp
26 */
27
28#include <sys/types.h>
29#include <sys/ioctl.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <sys/param.h>
33#include <net/route.h>
34#include <sys/sysctl.h>
35#include <net/if_dl.h>
36
37#include <errno.h>
38#include <ifaddrs.h>
39#include <stddef.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43
44#define SALIGN (sizeof(long) - 1)
45#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
46
47int
48getifaddrs(struct ifaddrs **pif)
49{
50 int icnt = 1;
51 int dcnt = 0;
52 int ncnt = 0;
53 int mib[6];
54 size_t needed;
55 char *buf = NULL, *bufp;
56 char *next;
57 struct ifaddrs *cif = 0;
58 char *p, *p0;
59 struct rt_msghdr *rtm;
60 struct if_msghdr *ifm;
61 struct ifa_msghdr *ifam;
62 struct sockaddr_dl *dl;
63 struct sockaddr *sa;
64 u_short index = 0;
65 size_t len, alen, dlen;
66 struct ifaddrs *ifa, *ift;
67 int i;
68 char *data;
69 char *names;
70
71 mib[0] = CTL_NET;
72 mib[1] = PF_ROUTE;
73 mib[2] = 0; /* protocol */
74 mib[3] = 0; /* wildcard address family */
75 mib[4] = NET_RT_IFLIST;
76 mib[5] = 0; /* no flags */
77 while (1) {
78 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) {
79 free(buf);
80 return (-1);
81 }
82 if (needed == 0)
83 break;
84 if ((bufp = realloc(buf, needed)) == NULL) {
85 free(buf);
86 return (-1);
87 }
88 buf = bufp;
89 if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
90 if (errno == ENOMEM)
91 continue;
92 free(buf);
93 return (-1);
94 }
95 break;
96 }
97
98 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
99 rtm = (struct rt_msghdr *)next;
100 if (rtm->rtm_version != RTM_VERSION)
101 continue;
102 switch (rtm->rtm_type) {
103 case RTM_IFINFO:
104 ifm = (struct if_msghdr *)rtm;
105 if (ifm->ifm_addrs & RTA_IFP) {
106 index = ifm->ifm_index;
107 ++icnt;
108 dl = (struct sockaddr_dl *)(next +
109 rtm->rtm_hdrlen);
110 dcnt += SA_RLEN((struct sockaddr *)dl) +
111 ALIGNBYTES;
112 dcnt += sizeof(ifm->ifm_data);
113 ncnt += dl->sdl_nlen + 1;
114 } else
115 index = 0;
116 break;
117
118 case RTM_NEWADDR:
119 ifam = (struct ifa_msghdr *)rtm;
120 if (index && ifam->ifam_index != index)
121 abort(); /* XXX abort illegal in library */
122
123#define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD)
124 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
125 break;
126 p = next + rtm->rtm_hdrlen;
127 ++icnt;
128 /* Scan to look for length of address */
129 alen = 0;
130 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
131 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
132 == 0)
133 continue;
134 sa = (struct sockaddr *)p;
135 len = SA_RLEN(sa);
136 if (i == RTAX_IFA) {
137 alen = len;
138 break;
139 }
140 p += len;
141 }
142 for (p = p0, i = 0; i < RTAX_MAX; i++) {
143 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
144 == 0)
145 continue;
146 sa = (struct sockaddr *)p;
147 len = SA_RLEN(sa);
148 if (i == RTAX_NETMASK && sa->sa_len == 0)
149 dcnt += alen;
150 else
151 dcnt += len;
152 p += len;
153 }
154 break;
155 }
156 }
157
158 if (icnt + dcnt + ncnt == 1) {
159 *pif = NULL;
160 free(buf);
161 return (0);
162 }
163 data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
164 if (data == NULL) {
165 free(buf);
166 return(-1);
167 }
168
169 ifa = (struct ifaddrs *)data;
170 data += sizeof(struct ifaddrs) * icnt;
171 names = data + dcnt;
172
173 memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
174 ift = ifa;
175
176 index = 0;
177 for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
178 rtm = (struct rt_msghdr *)next;
179 if (rtm->rtm_version != RTM_VERSION)
180 continue;
181 switch (rtm->rtm_type) {
182 case RTM_IFINFO:
183 ifm = (struct if_msghdr *)rtm;
184 if (ifm->ifm_addrs & RTA_IFP) {
185 index = ifm->ifm_index;
186 dl = (struct sockaddr_dl *)(next +
187 rtm->rtm_hdrlen);
188
189 cif = ift;
190 ift->ifa_name = names;
191 ift->ifa_flags = (int)ifm->ifm_flags;
192 memcpy(names, dl->sdl_data, dl->sdl_nlen);
193 names[dl->sdl_nlen] = 0;
194 names += dl->sdl_nlen + 1;
195
196 ift->ifa_addr = (struct sockaddr *)data;
197 memcpy(data, dl,
198 ((struct sockaddr *)dl)->sa_len);
199 data += SA_RLEN((struct sockaddr *)dl);
200
201 /* ifm_data needs to be aligned */
202 ift->ifa_data = data = (void *)ALIGN(data);
203 dlen = rtm->rtm_hdrlen -
204 offsetof(struct if_msghdr, ifm_data);
205 if (dlen > sizeof(ifm->ifm_data))
206 dlen = sizeof(ifm->ifm_data);
207 memcpy(data, &ifm->ifm_data, dlen);
208 data += sizeof(ifm->ifm_data);
209
210 ift = (ift->ifa_next = ift + 1);
211 } else
212 index = 0;
213 break;
214
215 case RTM_NEWADDR:
216 ifam = (struct ifa_msghdr *)rtm;
217 if (index && ifam->ifam_index != index)
218 abort(); /* XXX abort illegal in library */
219
220 if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0)
221 break;
222 ift->ifa_name = cif->ifa_name;
223 ift->ifa_flags = cif->ifa_flags;
224 ift->ifa_data = NULL;
225 p = next + rtm->rtm_hdrlen;
226 /* Scan to look for length of address */
227 alen = 0;
228 for (p0 = p, i = 0; i < RTAX_MAX; i++) {
229 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
230 == 0)
231 continue;
232 sa = (struct sockaddr *)p;
233 len = SA_RLEN(sa);
234 if (i == RTAX_IFA) {
235 alen = len;
236 break;
237 }
238 p += len;
239 }
240 for (p = p0, i = 0; i < RTAX_MAX; i++) {
241 if ((RTA_MASKS & ifam->ifam_addrs & (1 << i))
242 == 0)
243 continue;
244 sa = (struct sockaddr *)p;
245 len = SA_RLEN(sa);
246 switch (i) {
247 case RTAX_IFA:
248 ift->ifa_addr = (struct sockaddr *)data;
249 memcpy(data, p, len);
250 data += len;
251 break;
252
253 case RTAX_NETMASK:
254 ift->ifa_netmask =
255 (struct sockaddr *)data;
256 if (sa->sa_len == 0) {
257 memset(data, 0, alen);
258 data += alen;
259 break;
260 }
261 memcpy(data, p, len);
262 data += len;
263 break;
264
265 case RTAX_BRD:
266 ift->ifa_broadaddr =
267 (struct sockaddr *)data;
268 memcpy(data, p, len);
269 data += len;
270 break;
271 }
272 p += len;
273 }
274
275
276 ift = (ift->ifa_next = ift + 1);
277 break;
278 }
279 }
280
281 free(buf);
282 if (--ift >= ifa) {
283 ift->ifa_next = NULL;
284 *pif = ifa;
285 } else {
286 *pif = NULL;
287 free(ifa);
288 }
289 return (0);
290}
291
292void
293freeifaddrs(struct ifaddrs *ifp)
294{
295 free(ifp);
296}
diff --git a/src/lib/libc/net/getnameinfo.3 b/src/lib/libc/net/getnameinfo.3
new file mode 100644
index 0000000000..d023b2523d
--- /dev/null
+++ b/src/lib/libc/net/getnameinfo.3
@@ -0,0 +1,265 @@
1.\" $OpenBSD: getnameinfo.3,v 1.46 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: getnameinfo.3,v 1.37 2005/01/05 03:23:05 itojun Exp $
3.\"
4.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
5.\" Copyright (C) 2000, 2001 Internet Software Consortium.
6.\"
7.\" Permission to use, copy, modify, and distribute this software for any
8.\" purpose with or without fee is hereby granted, provided that the above
9.\" copyright notice and this permission notice appear in all copies.
10.\"
11.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17.\" PERFORMANCE OF THIS SOFTWARE.
18.\"
19.Dd $Mdocdate: January 21 2014 $
20.Dt GETNAMEINFO 3
21.Os
22.Sh NAME
23.Nm getnameinfo
24.Nd socket address structure to hostname and service name
25.Sh SYNOPSIS
26.In sys/types.h
27.In sys/socket.h
28.In netdb.h
29.Ft int
30.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" "char *host" \
31 "size_t hostlen" "char *serv" "size_t servlen" "int flags"
32.Sh DESCRIPTION
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.In 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 RFC 4007.
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 Craig Metz
169.%T Protocol Independence Using the Sockets API
170.%B Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference
171.%D June 2000
172.Re
173.Sh STANDARDS
174The
175.Fn getnameinfo
176function is defined by the
177.St -p1003.1g-2000
178draft specification and documented in RFC 3493.
179.Pp
180.Rs
181.%A R. Gilligan
182.%A S. Thomson
183.%A J. Bound
184.%A J. McCann
185.%A W. Stevens
186.%D February 2003
187.%R RFC 3493
188.%T Basic Socket Interface Extensions for IPv6
189.Re
190.Pp
191.Rs
192.%A S. Deering
193.%A B. Haberman
194.%A T. Jinmei
195.%A E. Nordmark
196.%A B. Zill
197.%D March 2005
198.%R RFC 4007
199.%T IPv6 Scoped Address Architecture
200.Re
201.Sh CAVEATS
202.Fn getnameinfo
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;
232char addr[NI_MAXHOST];
233struct addrinfo hints, *res;
234int error;
235
236error = getnameinfo(sa, sa->sa_len, addr, sizeof(addr),
237 NULL, 0, NI_NAMEREQD);
238if (error == 0) {
239 memset(&hints, 0, sizeof(hints));
240 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
241 hints.ai_flags = AI_NUMERICHOST;
242 if (getaddrinfo(addr, "0", &hints, &res) == 0) {
243 /* malicious PTR record */
244 freeaddrinfo(res);
245 printf("bogus PTR record\en");
246 return -1;
247 }
248 /* addr is FQDN as a result of PTR lookup */
249} else {
250 /* addr is numeric string */
251 error = getnameinfo(sa, sa->sa_len, addr, sizeof(addr),
252 NULL, 0, NI_NUMERICHOST);
253}
254.Ed
255.Sh BUGS
256The implementation of
257.Fn getnameinfo
258is not thread-safe.
259.Pp
260.Ox
261intentionally uses a different
262.Dv NI_MAXHOST
263value from what
264.Tn "RFC 2553"
265suggests, to avoid buffer length handling mistakes.
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c
new file mode 100644
index 0000000000..a85106630c
--- /dev/null
+++ b/src/lib/libc/net/getnetbyaddr.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: getnetbyaddr.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32
33extern int _net_stayopen;
34
35struct netent *
36_getnetbyaddr(in_addr_t net, int type)
37{
38 struct netent *p;
39
40 setnetent(_net_stayopen);
41 while ((p = getnetent()))
42 if (p->n_addrtype == type && p->n_net == net)
43 break;
44 if (!_net_stayopen)
45 endnetent();
46 return (p);
47}
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
new file mode 100644
index 0000000000..e6540cf12c
--- /dev/null
+++ b/src/lib/libc/net/getnetbyname.c
@@ -0,0 +1,54 @@
1/* $OpenBSD: getnetbyname.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32#include <string.h>
33
34extern int _net_stayopen;
35
36struct netent *
37_getnetbyname(const char *name)
38{
39 struct netent *p;
40 char **cp;
41
42 setnetent(_net_stayopen);
43 while ((p = getnetent())) {
44 if (strcasecmp(p->n_name, name) == 0)
45 break;
46 for (cp = p->n_aliases; *cp != 0; cp++)
47 if (strcasecmp(*cp, name) == 0)
48 goto found;
49 }
50found:
51 if (!_net_stayopen)
52 endnetent();
53 return (p);
54}
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
new file mode 100644
index 0000000000..e0344e2dd0
--- /dev/null
+++ b/src/lib/libc/net/getnetent.3
@@ -0,0 +1,140 @@
1.\" $OpenBSD: getnetent.3,v 1.16 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt GETNETENT 3
32.Os
33.Sh NAME
34.Nm getnetent ,
35.Nm getnetbyaddr ,
36.Nm getnetbyname ,
37.Nm setnetent ,
38.Nm endnetent
39.Nd get network entry
40.Sh SYNOPSIS
41.In netdb.h
42.Ft struct netent *
43.Fn getnetent "void"
44.Ft struct netent *
45.Fn getnetbyname "const char *name"
46.Ft struct netent *
47.Fn getnetbyaddr "in_addr_t net" "int type"
48.Ft void
49.Fn setnetent "int stayopen"
50.Ft void
51.Fn endnetent "void"
52.Sh DESCRIPTION
53The
54.Fn getnetent ,
55.Fn getnetbyname ,
56and
57.Fn getnetbyaddr
58functions each return a pointer to an object with the following structure
59containing the broken-out fields of a line in the network database,
60.Pa /etc/networks .
61.Bd -literal -offset indent
62struct netent {
63 char *n_name; /* official name of net */
64 char **n_aliases; /* alias list */
65 int n_addrtype; /* net number type */
66 in_addr_t n_net; /* net number */
67};
68.Ed
69.Pp
70The members of this structure are:
71.Bl -tag -width n_addrtype
72.It Fa n_name
73The official name of the network.
74.It Fa n_aliases
75A null-terminated list of alternate names for the network.
76.It Fa n_addrtype
77The type of the network number returned; currently only
78.Dv AF_INET .
79.It Fa n_net
80The network number.
81Network numbers are returned in machine byte order.
82.El
83.Pp
84The
85.Fn getnetent
86function reads the next line of the file, opening the file if necessary.
87.Pp
88The
89.Fn setnetent
90function opens and rewinds the file.
91If the
92.Fa stayopen
93flag is non-zero,
94the net database will not be closed after each call to
95.Fn getnetbyname
96or
97.Fn getnetbyaddr .
98.Pp
99The
100.Fn endnetent
101function closes the file.
102.Pp
103The
104.Fn getnetbyname
105and
106.Fn getnetbyaddr
107functions search the domain name server if the system is configured to use one.
108If the search fails, or no name server is configured, they sequentially
109search from the beginning of the file until a matching net name or
110net address and type is found, or until
111.Dv EOF
112is encountered.
113Network numbers are supplied in host order.
114.Sh FILES
115.Bl -tag -width /etc/networks -compact
116.It Pa /etc/networks
117.El
118.Sh DIAGNOSTICS
119Null pointer (0) returned on
120.Dv EOF
121or error.
122.Sh SEE ALSO
123.Xr resolver 3 ,
124.Xr networks 5
125.Sh HISTORY
126The
127.Fn getnetent ,
128.Fn getnetbyaddr ,
129.Fn getnetbyname ,
130.Fn setnetent ,
131and
132.Fn endnetent
133functions appeared in
134.Bx 4.2 .
135.Sh BUGS
136The data space used by these functions is static; if future use
137requires the data, it should be copied before any subsequent calls
138to these functions overwrite it.
139Only Internet network numbers are currently understood.
140Expecting network numbers to fit in no more than 32 bits is naive.
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c
new file mode 100644
index 0000000000..57fe459e2b
--- /dev/null
+++ b/src/lib/libc/net/getnetent.c
@@ -0,0 +1,120 @@
1/* $OpenBSD: getnetent.c,v 1.13 2012/04/10 16:41:10 eric Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/param.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <arpa/inet.h>
35#include <netdb.h>
36#include <stdio.h>
37#include <string.h>
38
39#define MAXALIASES 35
40
41static FILE *netf;
42static char line[BUFSIZ+1];
43static struct netent net;
44static char *net_aliases[MAXALIASES];
45int _net_stayopen;
46
47void
48setnetent(int f)
49{
50 if (netf == NULL)
51 netf = fopen(_PATH_NETWORKS, "r" );
52 else
53 rewind(netf);
54 _net_stayopen |= f;
55}
56
57void
58endnetent(void)
59{
60 if (netf) {
61 fclose(netf);
62 netf = NULL;
63 }
64 _net_stayopen = 0;
65}
66
67struct netent *
68getnetent(void)
69{
70 char *p, *cp, **q;
71 size_t len;
72
73 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
74 return (NULL);
75again:
76 if ((p = fgetln(netf, &len)) == NULL)
77 return (NULL);
78 if (p[len-1] == '\n')
79 len--;
80 if (len >= sizeof(line) || len == 0)
81 goto again;
82 p = memcpy(line, p, len);
83 line[len] = '\0';
84 if (*p == '#')
85 goto again;
86 if ((cp = strchr(p, '#')) != NULL)
87 *cp = '\0';
88 net.n_name = p;
89 if (strlen(net.n_name) >= MAXHOSTNAMELEN-1)
90 net.n_name[MAXHOSTNAMELEN-1] = '\0';
91 cp = strpbrk(p, " \t");
92 if (cp == NULL)
93 goto again;
94 *cp++ = '\0';
95 while (*cp == ' ' || *cp == '\t')
96 cp++;
97 p = strpbrk(cp, " \t");
98 if (p != NULL)
99 *p++ = '\0';
100 net.n_net = inet_network(cp);
101 net.n_addrtype = AF_INET;
102 q = net.n_aliases = net_aliases;
103 cp = p;
104 while (cp && *cp) {
105 if (*cp == ' ' || *cp == '\t') {
106 cp++;
107 continue;
108 }
109 if (q < &net_aliases[MAXALIASES - 1]) {
110 *q++ = cp;
111 if (strlen(cp) >= MAXHOSTNAMELEN-1)
112 cp[MAXHOSTNAMELEN-1] = '\0';
113 }
114 cp = strpbrk(cp, " \t");
115 if (cp != NULL)
116 *cp++ = '\0';
117 }
118 *q = NULL;
119 return (&net);
120}
diff --git a/src/lib/libc/net/getpeereid.3 b/src/lib/libc/net/getpeereid.3
new file mode 100644
index 0000000000..9c5742a245
--- /dev/null
+++ b/src/lib/libc/net/getpeereid.3
@@ -0,0 +1,121 @@
1.\" $OpenBSD: getpeereid.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.Dd $Mdocdate: June 5 2013 $
30.Dt GETPEEREID 3
31.Os
32.Sh NAME
33.Nm getpeereid
34.Nd get effective user and group identification of locally-connected peer
35.Sh SYNOPSIS
36.In sys/types.h
37.In sys/socket.h
38.Ft int
39.Fn getpeereid "int s" "uid_t *euid" "gid_t *egid"
40.Sh DESCRIPTION
41.Fn getpeereid
42returns the effective user ID and group ID of the peer connected to
43a
44.Ux Ns -domain
45socket (see
46.Xr unix 4 ) .
47The argument
48.Fa s
49must be of type
50.Dv SOCK_STREAM
51or
52.Dv SOCK_SEQPACKET .
53.Pp
54One common use is for
55.Ux Ns -domain
56servers to determine the credentials of clients that have connected to it.
57.Pp
58.Fn getpeereid
59takes three parameters:
60.Bl -bullet
61.It
62.Fa s
63contains the file descriptor of the socket whose peer credentials
64should be looked up.
65.It
66.Fa euid
67points to a
68.Li uid_t
69variable into which the effective user ID for the connected peer will
70be stored.
71.It
72.Fa egid
73points to a
74.Li gid_t
75variable into which the effective group ID for the connected peer will
76be stored.
77.El
78.Sh RETURN VALUES
79If the call succeeds, a 0 is returned and
80.Fa euid
81and
82.Fa egid
83are set to the effective user ID and group ID of the connected peer.
84Otherwise,
85.Va errno
86is set and a value of \-1 is returned.
87.Sh ERRORS
88On failure,
89.Va errno
90is set to one of the following:
91.Bl -tag -width Er
92.It Bq Er EBADF
93The argument
94.Fa s
95is not a valid descriptor.
96.It Bq Er ENOTSOCK
97The argument
98.Fa s
99is a file, not a socket.
100.It Bq Er EOPNOTSUPP
101The socket is not in the
102.Ux Ns -domain .
103.It Bq Er ENOTCONN
104The socket is not connected.
105.It Bq Er ENOBUFS
106Insufficient resources were available in the system
107to perform the operation.
108.El
109.Sh SEE ALSO
110.Xr accept 2 ,
111.Xr bind 2 ,
112.Xr getpeername 2 ,
113.Xr getsockname 2 ,
114.Xr getsockopt 2 ,
115.Xr socket 2 ,
116.Xr unix 4
117.Sh HISTORY
118The
119.Fn getpeereid
120function call appeared in
121.Ox 3.0 .
diff --git a/src/lib/libc/net/getpeereid.c b/src/lib/libc/net/getpeereid.c
new file mode 100644
index 0000000000..208e541f17
--- /dev/null
+++ b/src/lib/libc/net/getpeereid.c
@@ -0,0 +1,36 @@
1/* $OpenBSD: getpeereid.c,v 1.1 2010/07/01 19:15:30 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2010 Theo de Raadt <deraadt@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/socket.h>
21
22int
23getpeereid(int s, uid_t *euid, gid_t *egid)
24{
25 struct sockpeercred creds;
26 socklen_t credslen = sizeof(creds);
27 int error;
28
29 error = getsockopt(s, SOL_SOCKET, SO_PEERCRED,
30 &creds, &credslen);
31 if (error)
32 return (error);
33 *euid = creds.uid;
34 *egid = creds.gid;
35 return (0);
36}
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c
new file mode 100644
index 0000000000..07fa33288d
--- /dev/null
+++ b/src/lib/libc/net/getproto.c
@@ -0,0 +1,59 @@
1/* $OpenBSD: getproto.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32#include <stdio.h>
33
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}
49
50struct protoent *
51getprotobynumber(int num)
52{
53 extern struct protoent_data _protoent_data;
54 static struct protoent proto;
55
56 if (getprotobynumber_r(num, &proto, &_protoent_data) != 0)
57 return (NULL);
58 return (&proto);
59}
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3
new file mode 100644
index 0000000000..cc2c69836a
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.3
@@ -0,0 +1,213 @@
1.\" $OpenBSD: getprotoent.3,v 1.18 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt GETPROTOENT 3
32.Os
33.Sh NAME
34.Nm getprotoent ,
35.Nm getprotoent_r ,
36.Nm getprotobynumber ,
37.Nm getprotobynumber_r ,
38.Nm getprotobyname ,
39.Nm getprotobyname_r ,
40.Nm setprotoent ,
41.Nm setprotoent_r ,
42.Nm endprotoent ,
43.Nm endprotoent_r
44.Nd get protocol entry
45.Sh SYNOPSIS
46.In netdb.h
47.Ft struct protoent *
48.Fn getprotoent "void"
49.Ft int
50.Fn getprotoent_r "struct protoent *protoent" "struct protoent_data *protoent_data"
51.Ft struct protoent *
52.Fn getprotobyname "const char *name"
53.Ft int
54.Fn getprotobyname_r "const char *name" "struct protoent *protoent" "struct protoent_data *protoent_data"
55.Ft struct protoent *
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
60.Fn setprotoent "int stayopen"
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"
67.Sh DESCRIPTION
68The
69.Fn getprotoent ,
70.Fn getprotobyname ,
71and
72.Fn getprotobynumber
73functions each return a pointer to an object with the following structure
74containing the broken-out fields of a line in the network protocol database,
75.Pa /etc/protocols .
76.Bd -literal -offset indent
77.Pp
78struct protoent {
79 char *p_name; /* official name of protocol */
80 char **p_aliases; /* alias list */
81 int p_proto; /* protocol number */
82};
83.Ed
84.Pp
85The members of this structure are:
86.Bl -tag -width p_aliases
87.It Fa p_name
88The official name of the protocol.
89.It Fa p_aliases
90A null-terminated list of alternate names for the protocol.
91.It Fa p_proto
92The protocol number.
93.El
94.Pp
95The
96.Fn getprotoent
97function reads the next line of the file, opening the file if necessary.
98.Pp
99The
100.Fn setprotoent
101function opens and rewinds the file.
102If the
103.Fa stayopen
104flag is non-zero,
105the protocol database will not be closed after each call to
106.Fn getprotobyname
107or
108.Fn getprotobynumber .
109.Pp
110The
111.Fn endprotoent
112function closes the file.
113.Pp
114The
115.Fn getprotobyname
116and
117.Fn getprotobynumber
118functions sequentially search from the beginning of the file until a
119matching protocol name or protocol number is found, or until
120.Dv EOF
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.
146.Sh RETURN VALUES
147The
148.Fn getprotoent ,
149.Fn getprotobyport ,
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.
164.Sh FILES
165.Bl -tag -width /etc/protocols -compact
166.It Pa /etc/protocols
167.El
168.Sh SEE ALSO
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.
190.Sh HISTORY
191The
192.Fn getprotoent ,
193.Fn getprotobynumber ,
194.Fn getprotobyname ,
195.Fn setprotoent ,
196and
197.Fn endprotoent
198functions appeared in
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 .
210.Sh BUGS
211The non-reentrant functions use a static data space; if the data is needed
212for future use, it should be copied before any subsequent calls overwrite it.
213Only the Internet protocols are currently understood.
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c
new file mode 100644
index 0000000000..f0705e0765
--- /dev/null
+++ b/src/lib/libc/net/getprotoent.c
@@ -0,0 +1,166 @@
1/* $OpenBSD: getprotoent.c,v 1.10 2007/09/02 15:19:17 deraadt Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/types.h>
32#include <sys/socket.h>
33
34#include <errno.h>
35#include <limits.h>
36#include <netdb.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40
41void
42setprotoent_r(int f, struct protoent_data *pd)
43{
44 if (pd->fp == NULL)
45 pd->fp = fopen(_PATH_PROTOCOLS, "r" );
46 else
47 rewind(pd->fp);
48 pd->stayopen |= f;
49}
50
51void
52endprotoent_r(struct protoent_data *pd)
53{
54 if (pd->fp) {
55 fclose(pd->fp);
56 pd->fp = NULL;
57 }
58 free(pd->aliases);
59 pd->aliases = NULL;
60 pd->maxaliases = 0;
61 free(pd->line);
62 pd->line = NULL;
63 pd->stayopen = 0;
64}
65
66int
67getprotoent_r(struct protoent *pe, struct protoent_data *pd)
68{
69 char *p, *cp, **q, *endp;
70 size_t len;
71 long l;
72 int serrno;
73
74 if (pd->fp == NULL && (pd->fp = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
75 return (-1);
76again:
77 if ((p = fgetln(pd->fp, &len)) == NULL)
78 return (-1);
79 if (len == 0 || *p == '#' || *p == '\n')
80 goto again;
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);
86 if (cp == NULL)
87 return (-1);
88 pd->line = pe->p_name = memcpy(cp, p, len);
89 cp[len] = '\0';
90 cp = strpbrk(cp, " \t");
91 if (cp == NULL)
92 goto again;
93 *cp++ = '\0';
94 while (*cp == ' ' || *cp == '\t')
95 cp++;
96 p = strpbrk(cp, " \t");
97 if (p != NULL)
98 *p++ = '\0';
99 l = strtol(cp, &endp, 10);
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;
114 if (p != NULL) {
115 cp = p;
116 while (cp && *cp) {
117 if (*cp == ' ' || *cp == '\t') {
118 cp++;
119 continue;
120 }
121 if (q == &pe->p_aliases[pd->maxaliases - 1]) {
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;
135 cp = strpbrk(cp, " \t");
136 if (cp != NULL)
137 *cp++ = '\0';
138 }
139 }
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);
165 return (&proto);
166}
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c
new file mode 100644
index 0000000000..749b6b3f13
--- /dev/null
+++ b/src/lib/libc/net/getprotoname.c
@@ -0,0 +1,67 @@
1/* $OpenBSD: getprotoname.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32#include <stdio.h>
33#include <string.h>
34
35int
36getprotobyname_r(const char *name, struct protoent *pe,
37 struct protoent_data *pd)
38{
39 char **cp;
40 int error;
41
42 setprotoent_r(pd->stayopen, pd);
43 while ((error = getprotoent_r(pe, pd)) == 0) {
44 if (strcmp(pe->p_name, name) == 0)
45 break;
46 for (cp = pe->p_aliases; *cp != 0; cp++)
47 if (strcmp(*cp, name) == 0)
48 goto found;
49 }
50found:
51 if (!pd->stayopen && pd->fp != NULL) {
52 fclose(pd->fp);
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);
67}
diff --git a/src/lib/libc/net/getrrsetbyname.3 b/src/lib/libc/net/getrrsetbyname.3
new file mode 100644
index 0000000000..677b2a4c2e
--- /dev/null
+++ b/src/lib/libc/net/getrrsetbyname.3
@@ -0,0 +1,165 @@
1.\" $OpenBSD: getrrsetbyname.3,v 1.18 2013/07/16 15:21:11 schwarze Exp $
2.\"
3.\" Copyright (C) 2000, 2001 Internet Software Consortium.
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
10.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
11.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
12.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
13.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd $Mdocdate: July 16 2013 $
19.Dt GETRRSETBYNAME 3
20.Os
21.Sh NAME
22.Nm freerrset ,
23.Nm getrrsetbyname
24.Nd retrieve DNS records
25.Sh SYNOPSIS
26.In netdb.h
27.Ft int
28.Fn getrrsetbyname "const char *hostname" "unsigned int rdclass" \
29"unsigned int rdtype" "unsigned int flags" "struct rrsetinfo **res"
30.Ft void
31.Fn freerrset "struct rrsetinfo *rrset"
32.Sh DESCRIPTION
33.Fn getrrsetbyname
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.Bl -tag -width ERRSET_NOMEMORY
127.It Bq Er ERRSET_NONAME
128The name does not exist.
129.It Bq Er ERRSET_NODATA
130The name exists, but does not have data of the desired type.
131.It Bq Er ERRSET_NOMEMORY
132Memory could not be allocated.
133.It Bq Er ERRSET_INVAL
134A parameter is invalid.
135.It Bq Er ERRSET_FAIL
136Other failure.
137.El
138.Sh SEE ALSO
139.Xr resolver 3 ,
140.Xr resolv.conf 5 ,
141.Xr named 8
142.Sh HISTORY
143.Fn getrrsetbyname
144first appeared in
145.Ox 3.0 .
146The API first appeared in ISC BIND version 9.
147.Sh AUTHORS
148.An Jakob Schlyter Aq Mt jakob@openbsd.org
149.Sh CAVEATS
150The
151.Dv RRSET_VALIDATED
152flag in
153.Li rri_flags
154is set if the AD (authenticated data) bit in the DNS answer is
155set.
156This flag
157.Em should not
158be trusted unless the transport between the nameserver and the resolver
159is secure (e.g. IPsec, trusted network, loopback communication).
160.Sh BUGS
161The data in
162.Li *rdi_data
163should be returned in uncompressed wire format.
164Currently, the data is in compressed format and the caller can't
165uncompress since it doesn't have the full message.
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c
new file mode 100644
index 0000000000..beb8943af6
--- /dev/null
+++ b/src/lib/libc/net/getservbyname.c
@@ -0,0 +1,70 @@
1/* $OpenBSD: getservbyname.c,v 1.10 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32#include <stdio.h>
33#include <string.h>
34
35int
36getservbyname_r(const char *name, const char *proto, struct servent *se,
37 struct servent_data *sd)
38{
39 char **cp;
40 int error;
41
42 setservent_r(sd->stayopen, sd);
43 while ((error = getservent_r(se, sd)) == 0) {
44 if (strcmp(name, se->s_name) == 0)
45 goto gotname;
46 for (cp = se->s_aliases; *cp; cp++)
47 if (strcmp(name, *cp) == 0)
48 goto gotname;
49 continue;
50gotname:
51 if (proto == 0 || strcmp(se->s_proto, proto) == 0)
52 break;
53 }
54 if (!sd->stayopen && sd->fp != NULL) {
55 fclose(sd->fp);
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);
70}
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c
new file mode 100644
index 0000000000..46679ba366
--- /dev/null
+++ b/src/lib/libc/net/getservbyport.c
@@ -0,0 +1,64 @@
1/* $OpenBSD: getservbyport.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <netdb.h>
32#include <stdio.h>
33#include <string.h>
34
35int
36getservbyport_r(int port, const char *proto, struct servent *se,
37 struct servent_data *sd)
38{
39 int error;
40
41 setservent_r(sd->stayopen, sd);
42 while ((error = getservent_r(se, sd)) == 0) {
43 if (se->s_port != port)
44 continue;
45 if (proto == 0 || strcmp(se->s_proto, proto) == 0)
46 break;
47 }
48 if (!sd->stayopen && sd->fp != NULL) {
49 fclose(sd->fp);
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);
64}
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3
new file mode 100644
index 0000000000..29dd3eb5f4
--- /dev/null
+++ b/src/lib/libc/net/getservent.3
@@ -0,0 +1,220 @@
1.\" $OpenBSD: getservent.3,v 1.21 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt GETSERVENT 3
32.Os
33.Sh NAME
34.Nm getservent ,
35.Nm getservent_r ,
36.Nm getservbyport ,
37.Nm getservbyport_r ,
38.Nm getservbyname ,
39.Nm getservbyname_r ,
40.Nm setservent ,
41.Nm setservent_r ,
42.Nm endservent ,
43.Nm endservent_r
44.Nd get service entry
45.Sh SYNOPSIS
46.In netdb.h
47.Ft struct servent *
48.Fn getservent "void"
49.Ft int
50.Fn getservent_r "struct servent *servent" "struct servent_data *servent_data"
51.Ft struct servent *
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"
55.Ft struct servent *
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"
59.Ft void
60.Fn setservent "int stayopen"
61.Ft 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"
67.Sh DESCRIPTION
68The
69.Fn getservent ,
70.Fn getservbyname ,
71and
72.Fn getservbyport
73functions each return a pointer to an object with the following structure
74containing the broken-out fields of a line in the network services database,
75.Pa /etc/services .
76.Bd -literal -offset indent
77struct servent {
78 char *s_name; /* official name of service */
79 char **s_aliases; /* alias list */
80 int s_port; /* port service resides at */
81 char *s_proto; /* protocol to use */
82};
83.Ed
84.Pp
85The members of this structure are:
86.Bl -tag -width s_aliases
87.It Fa s_name
88The official name of the service.
89.It Fa s_aliases
90A null-terminated list of alternate names for the service.
91.It Fa s_port
92The port number at which the service resides.
93Port numbers are returned in network byte order.
94.It Fa s_proto
95The name of the protocol to use when contacting the service.
96.El
97.Pp
98The
99.Fn getservent
100function reads the next line of the file, opening the file if necessary.
101.Pp
102The
103.Fn setservent
104function opens and rewinds the file.
105If the
106.Fa stayopen
107flag is non-zero,
108the services database will not be closed after each call to
109.Fn getservbyname
110or
111.Fn getservbyport .
112.Pp
113The
114.Fn endservent
115function closes the file.
116.Pp
117The
118.Fn getservbyname
119and
120.Fn getservbyport
121functions sequentially search from the beginning of the file until a
122matching protocol name or port number (specified in network byte order)
123is found, or until
124.Dv EOF
125is encountered.
126If a protocol name is also supplied (non-null),
127searches must also match the protocol.
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.
170.Sh FILES
171.Bl -tag -width /etc/services -compact
172.It Pa /etc/services
173.El
174.Sh SEE ALSO
175.Xr getprotoent 3 ,
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.
197.Sh HISTORY
198The
199.Fn getservent ,
200.Fn getservbyport ,
201.Fn getservbyname ,
202.Fn setservent ,
203and
204.Fn endservent
205functions appeared in
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 .
217.Sh BUGS
218The non-reentrant functions use static data storage; if the data is needed
219for future use, it should be copied before any subsequent calls overwrite it.
220Expecting port numbers to fit in a 32-bit quantity is probably naive.
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c
new file mode 100644
index 0000000000..c81a4cf3e2
--- /dev/null
+++ b/src/lib/libc/net/getservent.c
@@ -0,0 +1,168 @@
1/* $OpenBSD: getservent.c,v 1.12 2007/09/02 15:19:17 deraadt Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/types.h>
32#include <sys/socket.h>
33
34#include <errno.h>
35#include <limits.h>
36#include <netdb.h>
37#include <stdio.h>
38#include <string.h>
39#include <stdlib.h>
40
41void
42setservent_r(int f, struct servent_data *sd)
43{
44 if (sd->fp == NULL)
45 sd->fp = fopen(_PATH_SERVICES, "r" );
46 else
47 rewind(sd->fp);
48 sd->stayopen |= f;
49}
50
51void
52endservent_r(struct servent_data *sd)
53{
54 if (sd->fp) {
55 fclose(sd->fp);
56 sd->fp = NULL;
57 }
58 free(sd->aliases);
59 sd->aliases = NULL;
60 sd->maxaliases = 0;
61 free(sd->line);
62 sd->line = NULL;
63 sd->stayopen = 0;
64}
65
66int
67getservent_r(struct servent *se, struct servent_data *sd)
68{
69 char *p, *cp, **q, *endp;
70 size_t len;
71 long l;
72 int serrno;
73
74 if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "r" )) == NULL)
75 return (-1);
76again:
77 if ((p = fgetln(sd->fp, &len)) == NULL)
78 return (-1);
79 if (len == 0 || *p == '#' || *p == '\n')
80 goto again;
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);
86 if (cp == NULL)
87 return (-1);
88 sd->line = se->s_name = memcpy(cp, p, len);
89 cp[len] = '\0';
90 p = strpbrk(cp, " \t");
91 if (p == NULL)
92 goto again;
93 *p++ = '\0';
94 while (*p == ' ' || *p == '\t')
95 p++;
96 cp = strpbrk(p, ",/");
97 if (cp == NULL)
98 goto again;
99 *cp++ = '\0';
100 l = strtol(p, &endp, 10);
101 if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
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;
116 cp = strpbrk(cp, " \t");
117 if (cp != NULL)
118 *cp++ = '\0';
119 while (cp && *cp) {
120 if (*cp == ' ' || *cp == '\t') {
121 cp++;
122 continue;
123 }
124 if (q == &se->s_aliases[sd->maxaliases - 1]) {
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;
138 cp = strpbrk(cp, " \t");
139 if (cp != NULL)
140 *cp++ = '\0';
141 }
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);
167 return (&serv);
168}
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
new file mode 100644
index 0000000000..7787115a9d
--- /dev/null
+++ b/src/lib/libc/net/herror.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: herror.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
2
3/*
4 * ++Copyright++ 1987, 1993
5 * -
6 * Copyright (c) 1987, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither 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/uio.h>
57#include <netdb.h>
58#include <unistd.h>
59#include <string.h>
60
61const char * const h_errlist[] = {
62 "Resolver Error 0 (no error)",
63 "Unknown host", /* 1 HOST_NOT_FOUND */
64 "Host name lookup failure", /* 2 TRY_AGAIN */
65 "Unknown server error", /* 3 NO_RECOVERY */
66 "No address associated with name", /* 4 NO_ADDRESS */
67};
68const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
69
70extern int h_errno;
71
72/*
73 * herror --
74 * print the error indicated by the h_errno value.
75 */
76void
77herror(const char *s)
78{
79 struct iovec iov[4];
80 struct iovec *v = iov;
81
82 if (s && *s) {
83 v->iov_base = (char *)s;
84 v->iov_len = strlen(s);
85 v++;
86 v->iov_base = ": ";
87 v->iov_len = 2;
88 v++;
89 }
90 v->iov_base = (char *)hstrerror(h_errno);
91 v->iov_len = strlen(v->iov_base);
92 v++;
93 v->iov_base = "\n";
94 v->iov_len = 1;
95 writev(STDERR_FILENO, iov, (v - iov) + 1);
96}
97
98const char *
99hstrerror(int err)
100{
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");
106}
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c
new file mode 100644
index 0000000000..5ab4189597
--- /dev/null
+++ b/src/lib/libc/net/htonl.c
@@ -0,0 +1,21 @@
1/* $OpenBSD: htonl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <sys/types.h>
8#include <machine/endian.h>
9
10#undef htonl
11
12u_int32_t
13htonl(u_int32_t x)
14{
15#if BYTE_ORDER == LITTLE_ENDIAN
16 u_char *s = (u_char *)&x;
17 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
18#else
19 return x;
20#endif
21}
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c
new file mode 100644
index 0000000000..c8b73fdbb7
--- /dev/null
+++ b/src/lib/libc/net/htons.c
@@ -0,0 +1,21 @@
1/* $OpenBSD: htons.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <sys/types.h>
8#include <machine/endian.h>
9
10#undef htons
11
12u_int16_t
13htons(u_int16_t x)
14{
15#if BYTE_ORDER == LITTLE_ENDIAN
16 u_char *s = (u_char *) &x;
17 return (u_int16_t)(s[0] << 8 | s[1]);
18#else
19 return x;
20#endif
21}
diff --git a/src/lib/libc/net/if_indextoname.3 b/src/lib/libc/net/if_indextoname.3
new file mode 100644
index 0000000000..5e6e7f2fdb
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.3
@@ -0,0 +1,143 @@
1.\" $OpenBSD: if_indextoname.3,v 1.15 2014/01/21 03:15:45 schwarze Exp $
2.\" Copyright (c) 1983, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. Neither the name of the University nor the names of its contributors
14.\" may be used to endorse or promote products derived from this software
15.\" without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
30.\"
31.Dd $Mdocdate: January 21 2014 $
32.Dt IF_NAMETOINDEX 3
33.Os
34.Sh NAME
35.Nm if_nametoindex ,
36.Nm if_indextoname ,
37.Nm if_nameindex ,
38.Nm if_freenameindex
39.Nd convert interface index to name, and vice versa
40.Sh SYNOPSIS
41.In sys/types.h
42.In sys/socket.h
43.In net/if.h
44.Ft "unsigned int"
45.Fn if_nametoindex "const char *ifname"
46.Ft "char *"
47.Fn if_indextoname "unsigned int ifindex" "char *ifname"
48.Ft "struct if_nameindex *"
49.Fn if_nameindex "void"
50.Ft "void"
51.Fn if_freenameindex "struct if_nameindex *ptr"
52.Sh DESCRIPTION
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.In 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.In 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.Sh STANDARDS
134.Rs
135.%A R. Gilligan
136.%A S. Thomson
137.%A J. Bound
138.%A J. McCann
139.%A W. Stevens
140.%D February 2003
141.%R RFC 3493
142.%T Basic Socket Interface Extensions for IPv6
143.Re
diff --git a/src/lib/libc/net/if_indextoname.c b/src/lib/libc/net/if_indextoname.c
new file mode 100644
index 0000000000..f99e52e387
--- /dev/null
+++ b/src/lib/libc/net/if_indextoname.c
@@ -0,0 +1,86 @@
1/* $OpenBSD: if_indextoname.c,v 1.9 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_indextoname.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2533:
40 *
41 * The second function maps an interface index into its corresponding
42 * name.
43 *
44 * #include <net/if.h>
45 *
46 * char *if_indextoname(unsigned int ifindex, char *ifname);
47 *
48 * The ifname argument must point to a buffer of at least IF_NAMESIZE
49 * bytes into which the interface name corresponding to the specified
50 * index is returned. (IF_NAMESIZE is also defined in <net/if.h> and
51 * its value includes a terminating null byte at the end of the
52 * interface name.) This pointer is also the return value of the
53 * function. If there is no interface corresponding to the specified
54 * index, NULL is returned, and errno is set to ENXIO, if there was a
55 * system error (such as running out of memory), if_indextoname returns
56 * NULL and errno would be set to the proper value (e.g., ENOMEM).
57 */
58
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..c5a771869b
--- /dev/null
+++ b/src/lib/libc/net/if_nameindex.c
@@ -0,0 +1,146 @@
1/* $OpenBSD: if_nameindex.c,v 1.10 2010/09/24 13:29:29 claudio Exp $ */
2/* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if_dl.h>
32#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36
37/*
38 * From RFC 2553:
39 *
40 * 4.3 Return All Interface Names and Indexes
41 *
42 * The if_nameindex structure holds the information about a single
43 * interface and is defined as a result of including the <net/if.h>
44 * header.
45 *
46 * struct if_nameindex {
47 * unsigned int if_index;
48 * char *if_name;
49 * };
50 *
51 * The final function returns an array of if_nameindex structures, one
52 * structure per interface.
53 *
54 * struct if_nameindex *if_nameindex(void);
55 *
56 * The end of the array of structures is indicated by a structure with
57 * an if_index of 0 and an if_name of NULL. The function returns a NULL
58 * pointer upon an error, and would set errno to the appropriate value.
59 *
60 * The memory used for this array of structures along with the interface
61 * names pointed to by the if_name members is obtained dynamically.
62 * This memory is freed by the next function.
63 *
64 * 4.4. Free Memory
65 *
66 * The following function frees the dynamic memory that was allocated by
67 * if_nameindex().
68 *
69 * #include <net/if.h>
70 *
71 * void if_freenameindex(struct if_nameindex *ptr);
72 *
73 * The argument to this function must be a pointer that was returned by
74 * if_nameindex().
75 */
76
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}
141
142void
143if_freenameindex(struct if_nameindex *ptr)
144{
145 free(ptr);
146}
diff --git a/src/lib/libc/net/if_nametoindex.c b/src/lib/libc/net/if_nametoindex.c
new file mode 100644
index 0000000000..8bd792b949
--- /dev/null
+++ b/src/lib/libc/net/if_nametoindex.c
@@ -0,0 +1,81 @@
1/* $OpenBSD: if_nametoindex.c,v 1.8 2002/03/07 22:40:23 millert Exp $ */
2/* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $ */
3
4/*-
5 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * BSDI Id: if_nametoindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
27 */
28
29#include <sys/types.h>
30#include <sys/socket.h>
31#include <net/if.h>
32#include <net/if_dl.h>
33#include <ifaddrs.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37
38/*
39 * From RFC 2553:
40 *
41 * 4.1 Name-to-Index
42 *
43 *
44 * The first function maps an interface name into its corresponding
45 * index.
46 *
47 * #include <net/if.h>
48 *
49 * unsigned int if_nametoindex(const char *ifname);
50 *
51 * If the specified interface name does not exist, the return value is
52 * 0, and errno is set to ENXIO. If there was a system error (such as
53 * running out of memory), the return value is 0 and errno is set to the
54 * proper value (e.g., ENOMEM).
55 */
56
57unsigned int
58if_nametoindex(const char *ifname)
59{
60 struct ifaddrs *ifaddrs, *ifa;
61 unsigned int ni;
62
63 if (getifaddrs(&ifaddrs) < 0)
64 return(0);
65
66 ni = 0;
67
68 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
69 if (ifa->ifa_addr &&
70 ifa->ifa_addr->sa_family == AF_LINK &&
71 strcmp(ifa->ifa_name, ifname) == 0) {
72 ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
73 break;
74 }
75 }
76
77 freeifaddrs(ifaddrs);
78 if (!ni)
79 errno = ENXIO;
80 return(ni);
81}
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3
new file mode 100644
index 0000000000..e56ca0a59a
--- /dev/null
+++ b/src/lib/libc/net/inet.3
@@ -0,0 +1,355 @@
1.\" $OpenBSD: inet.3,v 1.26 2013/06/05 03:39:23 tedu Exp $
2.\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $
3.\"
4.\" Copyright (c) 1983, 1990, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. 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.\" @(#)inet.3 8.1 (Berkeley) 6/4/93
32.\"
33.Dd $Mdocdate: June 5 2013 $
34.Dt INET 3
35.Os
36.Sh NAME
37.Nm inet_aton ,
38.Nm inet_addr ,
39.Nm inet_network ,
40.Nm inet_pton ,
41.Nm inet_ntop ,
42.Nm inet_ntoa ,
43.Nm inet_makeaddr ,
44.Nm inet_netof ,
45.Nm inet_lnaof
46.Nd Internet address manipulation routines
47.Sh SYNOPSIS
48.In sys/types.h
49.In sys/socket.h
50.In netinet/in.h
51.In arpa/inet.h
52.Ft int
53.Fn inet_aton "const char *cp" "struct in_addr *addr"
54.Ft in_addr_t
55.Fn inet_addr "const char *cp"
56.Ft in_addr_t
57.Fn inet_network "const char *cp"
58.Ft int
59.Fn inet_pton "int af" "const char *src" "void *dst"
60.Ft const char *
61.Fn inet_ntop "int af" "const void *src" "char *dst" "socklen_t size"
62.Ft char *
63.Fn inet_ntoa "struct in_addr in"
64.Ft struct in_addr
65.Fn inet_makeaddr "in_addr_t net" "in_addr_t lna"
66.Ft in_addr_t
67.Fn inet_netof "struct in_addr in"
68.Ft in_addr_t
69.Fn inet_lnaof "struct in_addr in"
70.Sh DESCRIPTION
71The routines
72.Fn inet_aton ,
73.Fn inet_addr ,
74and
75.Fn inet_network
76interpret character strings representing
77numbers expressed in the Internet standard
78.Dq dot
79notation.
80.Pp
81The
82.Fn inet_aton
83routine interprets the specified character string as an Internet address,
84placing the address into the structure provided.
85It returns 1 if the string was successfully interpreted,
86or 0 if the string was invalid.
87.Pp
88The
89.Fn inet_addr
90and
91.Fn inet_network
92functions return numbers suitable for use
93as Internet addresses and Internet network
94numbers, respectively.
95Both functions return the constant
96.Dv INADDR_NONE
97if the specified character string is malformed.
98.Pp
99The
100.Fn inet_pton
101function converts a presentation format address (that is, printable form
102as held in a character string) to network format (usually a
103.Li struct in_addr
104or some other internal binary representation, in network byte order).
105It returns 1 if the address was valid for the specified address family;
1060 if the address wasn't parseable in the specified address family; or \-1
107if some system error occurred (in which case
108.Va errno
109will have been set).
110This function is presently valid for
111.Dv AF_INET
112and
113.Dv AF_INET6 .
114.Pp
115The function
116.Fn inet_ntop
117converts an address from network format (usually a
118.Li struct in_addr
119or some other binary form, in network byte order) to presentation format
120(suitable for external display purposes).
121It returns
122.Dv NULL
123if a system
124error occurs (in which case,
125.Va errno
126will have been set), or it returns a pointer to the destination string.
127.Pp
128The routine
129.Fn inet_ntoa
130takes an Internet address and returns an
131ASCII string representing the address in dot notation.
132.Pp
133The routine
134.Fn inet_makeaddr
135takes an Internet network number and a local
136network address and constructs an Internet address
137from it.
138.Pp
139The routines
140.Fn inet_netof
141and
142.Fn inet_lnaof
143break apart Internet host addresses, returning
144the network number and local network address part,
145respectively.
146.Pp
147All Internet addresses are returned in network
148order (bytes ordered from left to right).
149All network numbers and local address parts are
150returned as machine format integer values.
151.Sh INTERNET ADDRESSES (IP VERSION 4)
152Values specified using dot notation take one of the following forms:
153.Bd -literal -offset indent
154a.b.c.d
155a.b.c
156a.b
157a
158.Ed
159.Pp
160When four parts are specified, each is interpreted
161as a byte of data and assigned, from left to right,
162to the four bytes of an Internet address.
163Note that when an Internet address is viewed as a 32-bit
164integer quantity on a system that uses little-endian
165byte order
166(such as the Intel 386, 486 and Pentium processors)
167the bytes referred to above appear as
168.Dq Li d.c.b.a .
169That is, little-endian bytes are ordered from right to left.
170.Pp
171When a three part address is specified, the last
172part is interpreted as a 16-bit quantity and placed
173in the rightmost two bytes of the network address.
174This makes the three part address format convenient
175for specifying Class B network addresses as
176.Dq Li 128.net.host .
177.Pp
178When a two part address is supplied, the last part
179is interpreted as a 24-bit quantity and placed in
180the rightmost three bytes of the network address.
181This makes the two part address format convenient
182for specifying Class A network addresses as
183.Dq Li net.host .
184.Pp
185When only one part is given, the value is stored
186directly in the network address without any byte
187rearrangement.
188.Pp
189All numbers supplied as
190.Dq parts
191in a dot notation
192may be decimal, octal, or hexadecimal, as specified
193in the C language (i.e., a leading 0x or 0X implies
194hexadecimal; a leading 0 implies octal;
195otherwise, the number is interpreted as decimal).
196.Sh INTERNET ADDRESSES (IP VERSION 6)
197In order to support scoped IPv6 addresses,
198.Xr getaddrinfo 3
199and
200.Xr getnameinfo 3
201are recommended rather than the functions presented here.
202.Pp
203The presentation format of an IPv6 address is given in RFC 4291:
204.Pp
205There are three conventional forms for representing IPv6 addresses as
206text strings:
207.Bl -enum
208.It
209The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
210hexadecimal values of the eight 16-bit pieces of the address.
211Examples:
212.Bd -literal -offset indent
213FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2141080:0:0:0:8:800:200C:417A
215.Ed
216.Pp
217Note that it is not necessary to write the leading zeros in an
218individual field, but there must be at least one numeral in
219every field (except for the case described in 2.).
220.It
221Due to the method of allocating certain styles of IPv6
222addresses, it will be common for addresses to contain long
223strings of zero bits.
224In order to make writing addresses
225containing zero bits easier, a special syntax is available to
226compress the zeros.
227The use of
228.Dq \&:\&:
229indicates multiple groups
230of 16 bits of zeros.
231The
232.Dq \&:\&:
233can only appear once in an
234address.
235The
236.Dq \&:\&:
237can also be used to compress the leading and/or trailing zeros in an address.
238.Pp
239For example the following addresses:
240.Bd -literal -offset indent
2411080:0:0:0:8:800:200C:417A a unicast address
242FF01:0:0:0:0:0:0:43 a multicast address
2430:0:0:0:0:0:0:1 the loopback address
2440:0:0:0:0:0:0:0 the unspecified addresses
245.Ed
246.Pp
247may be represented as:
248.Bd -literal -offset indent
2491080::8:800:200C:417A a unicast address
250FF01::43 a multicast address
251::1 the loopback address
252:: the unspecified addresses
253.Ed
254.It
255An alternative form that is sometimes more convenient when
256dealing with a mixed environment of IPv4 and IPv6 nodes is
257x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
258of the six high-order 16-bit pieces of the address, and the 'd's
259are the decimal values of the four low-order 8-bit pieces of the
260address (standard IPv4 representation).
261Examples:
262.Bd -literal -offset indent
2630:0:0:0:0:0:13.1.68.3
2640:0:0:0:0:FFFF:129.144.52.38
265.Ed
266.Pp
267or in compressed form:
268.Bd -literal -offset indent
269::13.1.68.3
270::FFFF:129.144.52.38
271.Ed
272.El
273.Sh SEE ALSO
274.Xr byteorder 3 ,
275.Xr gethostbyname 3 ,
276.Xr getnetent 3 ,
277.Xr inet_net 3 ,
278.Xr hosts 5 ,
279.Xr networks 5
280.Sh STANDARDS
281The
282.Nm inet_ntop
283and
284.Nm inet_pton
285functions conform to the IETF IPv6 BSD API and address formatting
286specifications.
287Note that
288.Nm inet_pton
289does not accept 1-, 2-, or 3-part dotted addresses; all four parts
290must be specified.
291This is a narrower input set than that accepted by
292.Nm inet_aton .
293.Pp
294.Rs
295.%A R. Gilligan
296.%A S. Thomson
297.%A J. Bound
298.%A J. McCann
299.%A W. Stevens
300.%D February 2003
301.%R RFC 3493
302.%T Basic Socket Interface Extensions for IPv6
303.Re
304.Pp
305.Rs
306.%A R. Hinden
307.%A S. Deering
308.%D February 2006
309.%R RFC 4291
310.%T IP Version 6 Addressing Architecture
311.Re
312.Sh HISTORY
313The
314.Nm inet_addr ,
315.Nm inet_network ,
316.Nm inet_makeaddr ,
317.Nm inet_lnaof ,
318and
319.Nm inet_netof
320functions appeared in
321.Bx 4.2 .
322The
323.Nm inet_aton
324and
325.Nm inet_ntoa
326functions appeared in
327.Bx 4.3 .
328The
329.Nm inet_pton
330and
331.Nm inet_ntop
332functions appeared in BIND 4.9.4.
333.Sh BUGS
334The value
335.Dv INADDR_NONE
336(0xffffffff) is a valid broadcast address, but
337.Fn inet_addr
338cannot return that value without indicating failure.
339Also,
340.Fn inet_addr
341should have been designed to return a
342.Li struct in_addr .
343The newer
344.Fn inet_aton
345function does not share these problems, and almost all existing code
346should be modified to use
347.Fn inet_aton
348instead.
349.Pp
350The problem of host byte ordering versus network byte ordering is
351confusing.
352.Pp
353The string returned by
354.Fn inet_ntoa
355resides in a static memory area.
diff --git a/src/lib/libc/net/inet6_opt_init.3 b/src/lib/libc/net/inet6_opt_init.3
new file mode 100644
index 0000000000..dd7ab53f6f
--- /dev/null
+++ b/src/lib/libc/net/inet6_opt_init.3
@@ -0,0 +1,328 @@
1.\" $OpenBSD: inet6_opt_init.3,v 1.6 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: inet6_opt_init.3,v 1.7 2004/12/27 05:08:23 itojun Exp $
3.\"
4.\" Copyright (C) 2004 WIDE Project.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the project nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: January 21 2014 $
32.Dt INET6_OPT_INIT 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_opt_init ,
37.Nm inet6_opt_append ,
38.Nm inet6_opt_finish ,
39.Nm inet6_opt_set_val ,
40.Nm inet6_opt_next ,
41.Nm inet6_opt_find ,
42.Nm inet6_opt_get_val
43.Nd IPv6 Hop-by-Hop and Destination Options manipulation
44.\"
45.Sh SYNOPSIS
46.In netinet/in.h
47.Ft "int"
48.Fn inet6_opt_init "void *extbuf" "socklen_t extlen"
49.Ft "int"
50.Fn inet6_opt_append "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t len" "u_int8_t align" "void **databufp"
51.Ft "int"
52.Fn inet6_opt_finish "void *extbuf" "socklen_t extlen" "int offset"
53.Ft "int"
54.Fn inet6_opt_set_val "void *databuf" "int offset" "void *val" "socklen_t vallen"
55.Ft "int"
56.Fn inet6_opt_next "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t *typep" "socklen_t *lenp" "void **databufp"
57.Ft "int"
58.Fn inet6_opt_find "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t *lenp" "void **databufp"
59.Ft "int"
60.Fn inet6_opt_get_val "void *databuf" "socklen_t offset" "void *val" "socklen_t vallen"
61.\"
62.Sh DESCRIPTION
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.
68These functions use the
69formatting rules specified in Appendix B in RFC 2460, i.e. that the
70largest field is placed last in the option.
71The function prototypes
72for these functions are all contained in the header file
73.In netinet/in.h .
74.\"
75.Ss inet6_opt_init
76The
77.Fn inet6_opt_init
78function
79returns the number of bytes needed for an empty
80extension header, one without any options.
81If the
82.Va extbuf
83argument points to a valid section of memory
84then the
85.Fn inet6_opt_init
86function also initializes the extension header's length field.
87When attempting to initialize an extension buffer passed in the
88.Va extbuf
89argument,
90.Fa extlen
91must be a positive multiple of 8 or else the function fails and
92returns \-1 to the caller.
93.\"
94.Ss inet6_opt_append
95The
96.Fn inet6_opt_append
97function can perform different jobs.
98When a valid
99.Fa extbuf
100argument is supplied it appends an option to the extension buffer and
101returns the updated total length as well as a pointer to the newly
102created option in
103.Fa databufp .
104If the value
105of
106.Fa extbuf
107is
108.Dv NULL
109then the
110.Fn inet6_opt_append
111function only reports what the total length would
112be if the option were actually appended.
113The
114.Fa len
115and
116.Fa align
117arguments specify the length of the option and the required data
118alignment which must be used when appending the option.
119The
120.Fa offset
121argument should be the length returned by the
122.Fn inet6_opt_init
123function or a previous call to
124.Fn inet6_opt_append .
125.Pp
126The
127.Fa type
128argument is the 8-bit option type.
129.Pp
130After
131.Fn inet6_opt_append
132has been called, the application can use the buffer pointed to by
133.Fa databufp
134directly, or use
135.Fn inet6_opt_set_val
136to specify the data to be contained in the option.
137.Pp
138Option types of
139.Li 0
140and
141.Li 1
142are reserved for the
143.Li Pad1
144and
145.Li PadN
146options.
147All other values from 2 through 255 may be used by applications.
148.Pp
149The length of the option data is contained in an 8-bit value and so
150may contain any value from 0 through 255.
151.Pp
152The
153.Fa align
154parameter must have a value of 1, 2, 4, or 8 and cannot exceed the
155value of
156.Fa len .
157The alignment values represent no alignment, 16-bit, 32-bit and 64-bit
158alignments respectively.
159.\"
160.Ss inet6_opt_finish
161The
162.Fn inet6_opt_finish
163calculates the final padding necessary to make the extension header a
164multiple of 8 bytes, as required by the IPv6 extension header
165specification, and returns the extension header's updated total
166length.
167The
168.Fa offset
169argument should be the length returned by
170.Fn inet6_opt_init
171or
172.Fn inet6_opt_append .
173When
174.Fa extbuf
175is not
176.Dv NULL
177the function also sets up the appropriate padding bytes by inserting a
178Pad1 or PadN option of the proper length.
179.Pp
180If the extension header is too small to contain the proper padding
181then an error of \-1 is returned to the caller.
182.\"
183.Ss inet6_opt_set_val
184The
185.Fn inet6_opt_set_val
186function inserts data items of various sizes into the data portion of
187the option.
188The
189.Fa databuf
190argument is a pointer to memory that was returned by the
191.Fn inet6_opt_append
192call and the
193.Fa offset
194argument specifies where the option should be placed in the
195data buffer.
196The
197.Fa val
198argument points to an area of memory containing the data to be
199inserted into the extension header, and the
200.Fa vallen
201argument indicates how much data to copy.
202.Pp
203The caller should ensure that each field is aligned on its natural
204boundaries as described in Appendix B of RFC 2460.
205.Pp
206The function returns the offset for the next field which is calculated as
207.Fa offset
208+
209.Fa vallen
210and is used when composing options with multiple fields.
211.\"
212.Ss inet6_opt_next
213The
214.Fn inet6_opt_next
215function parses received extension headers.
216The
217.Fa extbuf
218and
219.Fa extlen
220arguments specify the location and length of the extension header
221being parsed.
222The
223.Fa offset
224argument should either be zero, for the first option, or the length value
225returned by a previous call to
226.Fn inet6_opt_next
227or
228.Fn inet6_opt_find .
229The return value specifies the position where to continue scanning the
230extension buffer.
231The option is returned in the arguments
232.Fa typep , lenp ,
233and
234.Fa databufp .
235.Fa typep , lenp ,
236and
237.Fa databufp
238point to the 8-bit option type, the 8-bit option length and the option
239data respectively.
240This function does not return any PAD1 or PADN options.
241When an error occurs or there are no more options the return
242value is \-1.
243.\"
244.Ss inet6_opt_find
245The
246.Fn inet6_opt_find
247function searches the extension buffer for a particular option type,
248passed in through the
249.Fa type
250argument.
251If the option is found then the
252.Fa lenp
253and
254.Fa databufp
255arguments are updated to point to the option's length and data
256respectively.
257.Fa extbuf
258and
259.Fa extlen
260must point to a valid extension buffer and give its length.
261The
262.Fa offset
263argument can be used to search from a location anywhere in the
264extension header.
265.Ss inet6_opt_get_val
266The
267.Fn inet6_opt_get_val
268function extracts data items of various sizes in the data portion of
269the option.
270The
271.Fa databuf
272is a pointer returned by the
273.Fn inet6_opt_next
274or
275.Fn inet6_opt_find
276functions.
277The
278.Fa val
279argument points to where the data will be extracted.
280The
281.Fa offset
282argument specifies from where in the data portion of the option the
283value should be extracted; the first byte of option data is specified
284by an offset of zero.
285.Pp
286It is expected that each field is aligned on its natural boundaries as
287described in Appendix B of RFC 2460.
288.Pp
289The function returns the offset for the next field
290by calculating
291.Fa offset
292+
293.Fa vallen
294which can be used when extracting option content with multiple fields.
295Robust receivers must verify alignment before calling this function.
296.\"
297.Sh EXAMPLES
298RFC 3542 gives comprehensive examples in Section 23.
299KAME also provides examples in the
300.Pa advapitest
301directory of its kit.
302.\"
303.Sh DIAGNOSTICS
304All the functions return
305\-1
306on an error.
307.\"
308.Sh STANDARDS
309.Rs
310.%A S. Deering
311.%A R. Hinden
312.%D December 1998
313.%R RFC 2460
314.%T Internet Protocol, Version 6 (IPv6) Specification
315.Re
316.Pp
317.Rs
318.%A W. Stevens
319.%A M. Thomas
320.%A E. Nordmark
321.%A T. Jinmei
322.%D May 2003
323.%R RFC 3542
324.%T Advanced Sockets Application Program Interface (API) for IPv6
325.Re
326.Sh HISTORY
327The implementation first appeared in KAME advanced networking kit.
328.\"
diff --git a/src/lib/libc/net/inet6_option_space.3 b/src/lib/libc/net/inet6_option_space.3
new file mode 100644
index 0000000000..4b156636f7
--- /dev/null
+++ b/src/lib/libc/net/inet6_option_space.3
@@ -0,0 +1,442 @@
1.\" $OpenBSD: inet6_option_space.3,v 1.24 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: inet6_option_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $
3.\"
4.\" Copyright (C) 2004 WIDE Project.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the project nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: January 21 2014 $
32.Dt INET6_OPTION_SPACE 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_option_space ,
37.Nm inet6_option_init ,
38.Nm inet6_option_append ,
39.Nm inet6_option_alloc ,
40.Nm inet6_option_next ,
41.Nm inet6_option_find
42.Nd IPv6 Hop-by-Hop and Destination Option Manipulation
43.\"
44.Sh SYNOPSIS
45.In sys/types.h
46.In netinet/in.h
47.Ft "int"
48.Fn inet6_option_space "int nbytes"
49.Ft "int"
50.Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type"
51.Ft "int"
52.Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy"
53.Ft "u_int8_t *"
54.Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy"
55.Ft "int"
56.Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp"
57.Ft "int"
58.Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type"
59.\"
60.Sh DESCRIPTION
61.\"
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.In 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.\"
423.Sh STANDARDS
424.Rs
425.%A W. Stevens
426.%A M. Thomas
427.%D February 1998
428.%R RFC 2292
429.%T Advanced Sockets API for IPv6
430.Re
431.Pp
432.Rs
433.%A S. Deering
434.%A R. Hinden
435.%D December 1998
436.%R RFC 2460
437.%T Internet Protocol, Version 6 (IPv6) Specification
438.Re
439.\"
440.Sh HISTORY
441This implementation first appeared in the KAME advanced networking kit.
442.\"
diff --git a/src/lib/libc/net/inet6_rth_space.3 b/src/lib/libc/net/inet6_rth_space.3
new file mode 100644
index 0000000000..fcd023481f
--- /dev/null
+++ b/src/lib/libc/net/inet6_rth_space.3
@@ -0,0 +1,220 @@
1.\" $OpenBSD: inet6_rth_space.3,v 1.6 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: inet6_rth_space.3,v 1.7 2005/01/05 03:00:44 itojun Exp $
3.\"
4.\" Copyright (C) 2004 WIDE Project.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the project nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: January 21 2014 $
32.Dt INET6_RTH_SPACE 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_rth_space ,
37.Nm inet6_rth_init ,
38.Nm inet6_rth_add ,
39.Nm inet6_rth_reverse ,
40.Nm inet6_rth_segments ,
41.Nm inet6_rth_getaddr
42.Nd IPv6 Routing Header Options manipulation
43.\"
44.Sh SYNOPSIS
45.In netinet/in.h
46.Ft socklen_t
47.Fn inet6_rth_space "int" "int"
48.Ft "void *"
49.Fn inet6_rth_init "void *" "socklen_t" "int" "int"
50.Ft int
51.Fn inet6_rth_add "void *" "const struct in6_addr *"
52.Ft int
53.Fn inet6_rth_reverse "const void *" "void *"
54.Ft int
55.Fn inet6_rth_segments "const void *"
56.Ft "struct in6_addr *"
57.Fn inet6_rth_getaddr "const void *" "int"
58.\"
59.Sh DESCRIPTION
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.In netinet/in.h .
68The functions described in this manual page all operate
69on routing header structures which are defined in
70.In 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 STANDARDS
202.Rs
203.%A S. Deering
204.%A R. Hinden
205.%D December 1998
206.%R RFC 2460
207.%T Internet Protocol, Version 6 (IPv6) Specification
208.Re
209.Pp
210.Rs
211.%A W. Stevens
212.%A M. Thomas
213.%A E. Nordmark
214.%A T. Jinmei
215.%D May 2003
216.%R RFC 3542
217.%T Advanced Sockets Application Programming Interface (API) for IPv6
218.Re
219.Sh HISTORY
220The implementation first appeared in KAME advanced networking kit.
diff --git a/src/lib/libc/net/inet6_rthdr_space.3 b/src/lib/libc/net/inet6_rthdr_space.3
new file mode 100644
index 0000000000..c72e84ff1a
--- /dev/null
+++ b/src/lib/libc/net/inet6_rthdr_space.3
@@ -0,0 +1,310 @@
1.\" $OpenBSD: inet6_rthdr_space.3,v 1.23 2014/01/21 03:15:45 schwarze Exp $
2.\" $KAME: inet6_rthdr_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $
3.\"
4.\" Copyright (C) 2004 WIDE Project.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the project nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: January 21 2014 $
32.Dt INET6_RTHDR_SPACE 3
33.Os
34.\"
35.Sh NAME
36.Nm inet6_rthdr_space ,
37.Nm inet6_rthdr_init ,
38.Nm inet6_rthdr_add ,
39.Nm inet6_rthdr_lasthop ,
40.Nm inet6_rthdr_reverse ,
41.Nm inet6_rthdr_segments ,
42.Nm inet6_rthdr_getaddr ,
43.Nm inet6_rthdr_getflags
44.Nd IPv6 Routing Header Options Manipulation
45.\"
46.Sh SYNOPSIS
47.In sys/types.h
48.In netinet/in.h
49.Ft size_t
50.Fn inet6_rthdr_space "int type" "int segments"
51.Ft "struct cmsghdr *"
52.Fn inet6_rthdr_init "void *bp" "int type"
53.Ft int
54.Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags"
55.Ft int
56.Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags"
57.Ft int
58.Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out"
59.Ft int
60.Fn inet6_rthdr_segments "const struct cmsghdr *cmsg"
61.Ft "struct in6_addr *"
62.Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index"
63.Ft int
64.Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index"
65.\"
66.Sh DESCRIPTION
67Note:
68RFC 2292 has been superseded by RFC 3542.
69The use of functions described in this page is deprecated.
70See
71.Xr inet6_rth_space 3 .
72.Pp
73The RFC 2292 IPv6 Advanced API defined eight functions for
74applications to use for building and parsing routing headers.
75The
76eight functions are split into two groups, the first of which builds
77the header and the second of which can parse it.
78The function prototypes for these functions are all in the
79.In netinet/in.h
80header.
81Although direct manipulation of a routing header is possible,
82this set of APIs make it unnecessary and such direct manipulation
83should be avoided so that changes to the underlying structures do not
84break applications.
85.Pp
86Please note that RFC 2292 uses the term
87.Dq segments
88instead of the term
89.Dq addresses
90but they are considered equivalent for this manual page.
91.\"
92.Ss inet6_rthdr_space
93The
94.Fn inet6_rthdr_space
95function returns the number of bytes required to hold a routing header
96of the specified
97.Fa type
98and containing the specified number of
99.Fa segments .
100Only one
101.Fa type
102is supported,
103.Dv IPV6_RTHDR_TYPE_0 ,
104and it can hold from 1 to 23 segments.
105The return value includes the
106size of the
107.Vt cmsghdr
108structure that precedes the routing header and
109any required padding.
110.Pp
111A return value of 0 indicates an error.
112Either the type was specified
113incorrectly, or the number of segments was less than one or greater
114than 23.
115.Pp
116Note: The
117.Fn inet6_rthdr_space
118function only returns the size required by the routing header and does
119not allocate memory for the caller.
120.\"
121.Ss inet6_rthdr_init
122The
123.Fn inet6_rthdr_init
124function initializes a buffer, pointed to by
125.Fa bp
126with an appropriate
127.Li cmsghdr
128structure followed by a routing header of the specified
129.Fa type .
130.Pp
131The caller must use the
132.Fn inet6_rthdr_space
133function to determine the size of the buffer, and then allocate that
134buffer before calling
135.Fn inet6_rthdr_init .
136.Pp
137The return value is a pointer to a
138.Li cmsghdr
139structure, which is used as the first argument to the
140.Fn inet6_rthdr_add
141and
142.Fn inet6_rthdr_lasthop
143functions in order to construct the routing header.
144When an error occurs the return value is
145.Dv NULL .
146.\"
147.Ss inet6_rthdr_add
148The
149.Fn inet6_rthdr_add
150function adds the IPv6 address pointed to by
151.Fa addr
152to the end of the
153routing header being constructed and sets the type of this address to the
154value of
155.Fa flags .
156The
157.Fa flags
158must be either
159.Dv IPV6_RTHDR_LOOSE
160or
161.Dv IPV6_RTHDR_STRICT
162indicating whether loose or strict source routing is required.
163.Pp
164When the function succeeds it returns 0, otherwise \-1 is returned.
165.\"
166.Ss inet6_rthdr_lasthop
167The
168.Fn inet6_rthdr_lasthop
169function specifies the strict or loose flag for the final hop of a
170routing header.
171The
172.Fa flags
173argument must be either
174.Dv IPV6_RTHDR_LOOSE
175or
176.Dv IPV6_RTHDR_STRICT .
177.Pp
178The return value of the function is 0 upon success, and \-1 when an
179error has occurred.
180.Pp
181Please note that a routing header specifying
182.Li N
183intermediate nodes requires
184.Li N+1
185strict or loose flags meaning that
186.Fn inet6_rthdr_add
187must be called
188.Li N
189times and then
190.Fn inet6_rthdr_lasthop
191must be called once.
192.\"
193.Ss inet6_rthdr_reverse
194This function was never implemented.
195.Pp
196The following three functions provide an API for parsing a received
197routing header:
198.\"
199.Ss inet6_rthdr_segments
200The
201.Fn inet6_rthdr_segments
202function returns the number of segments contained in the routing
203header pointed to by the
204.Fa cmsg
205argument.
206On success the return value is from 1 to 23.
207When an error occurs, \-1 is returned.
208.\"
209.Ss inet6_rthdr_getaddr
210The
211.Fn inet6_rthdr_getaddr
212function returns a pointer to the IPv6 address specified by the
213.Fa index
214argument from the routing header pointed to by
215.Fa cmsg .
216The index must be between 1 and the number returned by
217.Fn inet6_rthdr_segments ,
218described above.
219An application must call
220.Fn inet6_rthdr_segments
221to obtain the number of segments in the routing header.
222.Pp
223If an error occurs,
224.Dv NULL
225is returned.
226.\"
227.Ss inet6_rthdr_getflags
228The
229.Fn inet6_rthdr_getflags
230function returns the flags value of the segment specified by
231.Fa index
232of the routing header pointed to by
233.Fa cmsg .
234The
235.Fa index
236argument must be between 0 and the value returned by
237.Fn inet6_rthdr_segments .
238The return value will be either
239.Dv IPV6_RTHDR_LOOSE
240or
241.Dv IPV6_RTHDR_STRICT
242indicating whether loose or strict source routing was requested for
243that segment.
244.Pp
245When an error occurs, \-1 is returned.
246.Pp
247Note: Flags begin at index 0 while segments begin at index 1, to
248maintain consistency with the terminology and figures in RFC 2460.
249.\"
250.Sh EXAMPLES
251RFC 2292 gives comprehensive examples in chapter 8.
252.\"
253.Sh DIAGNOSTICS
254The
255.Fn inet6_rthdr_space
256function returns 0 when an error occurs.
257.Pp
258The
259.Fn inet6_rthdr_add
260and
261.Fn inet6_rthdr_lasthop
262functions return 0 on success, and \-1 on error.
263.Pp
264The
265.Fn inet6_rthdr_init
266and
267.Fn inet6_rthdr_getaddr
268functions
269return
270.Dv NULL
271on error.
272.Pp
273The
274.Fn inet6_rthdr_segments
275and
276.Fn inet6_rthdr_getflags
277functions return \-1 on error.
278.\"
279.Sh SEE ALSO
280.Xr inet6 4 ,
281.Xr ip6 4
282.Sh STANDARDS
283.Rs
284.%A W. Stevens
285.%A M. Thomas
286.%D February 1998
287.%R RFC 2292
288.%T Advanced Sockets API for IPv6
289.Re
290.Pp
291.Rs
292.%A S. Deering
293.%A R. Hinden
294.%D December 1998
295.%R RFC 2460
296.%T Internet Protocol, Version 6 (IPv6) Specification
297.Re
298.\"
299.Sh HISTORY
300This implementation first appeared in the KAME advanced networking kit.
301.\"
302.Sh BUGS
303The
304.Fn inet6_rthdr_reverse
305function was never implemented.
306.\".Pp
307.\"This API is deprecated in favor of
308.\".Xr inet6_rth_space 3
309.\".Sh SEE ALSO
310.\".Xr inet6_rth_space 3
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
new file mode 100644
index 0000000000..18762ab522
--- /dev/null
+++ b/src/lib/libc/net/inet_addr.c
@@ -0,0 +1,175 @@
1/* $OpenBSD: inet_addr.c,v 1.10 2013/11/24 23:51:28 deraadt Exp $ */
2
3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
6 * Copyright (c) 1983, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither 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 <netinet/in.h>
57#include <arpa/inet.h>
58#include <ctype.h>
59
60/*
61 * Ascii internet address interpretation routine.
62 * The value returned is in network order.
63 */
64in_addr_t
65inet_addr(const char *cp)
66{
67 struct in_addr val;
68
69 if (inet_aton(cp, &val))
70 return (val.s_addr);
71 return (INADDR_NONE);
72}
73
74/*
75 * Check whether "cp" is a valid ascii representation
76 * of an Internet address and convert to a binary address.
77 * Returns 1 if the address is valid, 0 if not.
78 * This replaces inet_addr, the return value from which
79 * cannot distinguish between failure and a local broadcast address.
80 */
81int
82inet_aton(const char *cp, struct in_addr *addr)
83{
84 in_addr_t val;
85 int base, n;
86 char c;
87 u_int parts[4];
88 u_int *pp = parts;
89
90 c = *cp;
91 for (;;) {
92 /*
93 * Collect number up to ``.''.
94 * Values are specified as for C:
95 * 0x=hex, 0=octal, isdigit=decimal.
96 */
97 if (!isdigit((unsigned char)c))
98 return (0);
99 val = 0; base = 10;
100 if (c == '0') {
101 c = *++cp;
102 if (c == 'x' || c == 'X')
103 base = 16, c = *++cp;
104 else
105 base = 8;
106 }
107 for (;;) {
108 if (isascii((unsigned char)c) &&
109 isdigit((unsigned char)c)) {
110 val = (val * base) + (c - '0');
111 c = *++cp;
112 } else if (base == 16 &&
113 isascii((unsigned char)c) &&
114 isxdigit((unsigned char)c)) {
115 val = (val << 4) |
116 (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
117 c = *++cp;
118 } else
119 break;
120 }
121 if (c == '.') {
122 /*
123 * Internet format:
124 * a.b.c.d
125 * a.b.c (with c treated as 16 bits)
126 * a.b (with b treated as 24 bits)
127 */
128 if (pp >= parts + 3)
129 return (0);
130 *pp++ = val;
131 c = *++cp;
132 } else
133 break;
134 }
135 /*
136 * Check for trailing characters.
137 */
138 if (c != '\0' &&
139 (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
140 return (0);
141 /*
142 * Concoct the address according to
143 * the number of parts specified.
144 */
145 n = pp - parts + 1;
146 switch (n) {
147
148 case 0:
149 return (0); /* initial nondigit */
150
151 case 1: /* a -- 32 bits */
152 break;
153
154 case 2: /* a.b -- 8.24 bits */
155 if ((val > 0xffffff) || (parts[0] > 0xff))
156 return (0);
157 val |= parts[0] << 24;
158 break;
159
160 case 3: /* a.b.c -- 8.8.16 bits */
161 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
162 return (0);
163 val |= (parts[0] << 24) | (parts[1] << 16);
164 break;
165
166 case 4: /* a.b.c.d -- 8.8.8.8 bits */
167 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
168 return (0);
169 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
170 break;
171 }
172 if (addr)
173 addr->s_addr = htonl(val);
174 return (1);
175}
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c
new file mode 100644
index 0000000000..b1a58cd2c1
--- /dev/null
+++ b/src/lib/libc/net/inet_lnaof.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: inet_lnaof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/param.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34
35/*
36 * Return the local network address portion of an
37 * internet address; handles class a/b/c network
38 * number formats.
39 */
40in_addr_t
41inet_lnaof(struct in_addr in)
42{
43 in_addr_t i = ntohl(in.s_addr);
44
45 if (IN_CLASSA(i))
46 return ((i)&IN_CLASSA_HOST);
47 else if (IN_CLASSB(i))
48 return ((i)&IN_CLASSB_HOST);
49 else
50 return ((i)&IN_CLASSC_HOST);
51}
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c
new file mode 100644
index 0000000000..87d9325231
--- /dev/null
+++ b/src/lib/libc/net/inet_makeaddr.c
@@ -0,0 +1,54 @@
1/* $OpenBSD: inet_makeaddr.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/param.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34
35/*
36 * Formulate an Internet address from network + host. Used in
37 * building addresses stored in the ifnet structure.
38 */
39struct in_addr
40inet_makeaddr(in_addr_t net, in_addr_t host)
41{
42 in_addr_t addr;
43
44 if (net < 128)
45 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
46 else if (net < 65536)
47 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
48 else if (net < 16777216L)
49 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
50 else
51 addr = net | host;
52 addr = htonl(addr);
53 return (*(struct in_addr *)&addr);
54}
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3
new file mode 100644
index 0000000000..a0231b4537
--- /dev/null
+++ b/src/lib/libc/net/inet_net.3
@@ -0,0 +1,197 @@
1.\" $OpenBSD: inet_net.3,v 1.16 2013/06/05 03:39:23 tedu Exp $
2.\" $NetBSD: inet_net.3,v 1.1 1997/06/18 02:25:27 lukem Exp $
3.\"
4.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" This code is derived from software contributed to The NetBSD Foundation
8.\" by Luke Mewburn.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
23.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29.\" POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: June 5 2013 $
32.Dt INET_NET 3
33.Os
34.Sh NAME
35.Nm inet_net_ntop ,
36.Nm inet_net_pton
37.Nd Internet network number manipulation routines
38.Sh SYNOPSIS
39.In sys/types.h
40.In sys/socket.h
41.In netinet/in.h
42.In arpa/inet.h
43.Ft char *
44.Fn inet_net_ntop "int af" "const void *src" "int bits" "char *dst" "size_t size"
45.Ft int
46.Fn inet_net_pton "int af" "const char *src" "void *dst" "size_t size"
47.Sh DESCRIPTION
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 values for
88.Fa af
89currently supported are
90.Dv AF_INET
91and
92.Dv AF_INET6 .
93.Fa size
94is the size of the result buffer
95.Fa dst .
96.Sh NETWORK NUMBERS (IP VERSION 4)
97The external representation of Internet network numbers may be specified in
98one of the following forms:
99.Bd -literal -offset indent
100a
101a.b
102a.b.c
103a.b.c.d
104.Ed
105.Pp
106Any of the above four forms may have
107.Dq Li /bits
108appended where
109.Dq Li bits
110is in the range
111.Li 0-32
112and is used to explicitly specify the number of bits in the network address.
113When
114.Dq Li /bits
115is not specified the number of bits in the network address is calculated
116as the larger of the number of bits in the class to which the address
117belongs and the number of bits provided rounded up modulo 8.
118Examples:
119.Pp
120.Bl -tag -width 10.1.2.3/24 -offset indent -compact
121.It Li 10
122an 8-bit network number (class A), value
123.Li 10.0.0.0 .
124.It Li 192
125a 24-bit network number (class C), value
126.Li 192.0.0.0 .
127.It Li 10.10
128a 16-bit network number, value
129.Li 10.10.0.0 .
130.It Li 10.1.2
131a 24-bit network number, value
132.Li 10.1.2.0 .
133.It Li 10.1.2.3
134a 32-bit network number, value
135.Li 10.1.2.3 .
136.It Li 10.1.2.3/24
137a 24-bit network number (explicit), value
138.Li 10.1.2.3 .
139.El
140.Pp
141Note that when the number of bits is specified using
142.Dq Li /bits
143notation, the value of the address still includes all bits supplied
144in the external representation, even those bits which are the host
145part of an Internet address.
146Also, unlike
147.Xr inet_pton 3
148where the external representation is assumed to be a host address, the
149external representation for
150.Fn inet_net_pton
151is assumed to be a network address.
152Thus
153.Dq Li 10.1
154is assumed to be
155.Dq Li 10.1.0.0
156not
157.Dq Li 10.0.0.1
158.Pp
159All numbers supplied as
160.Dq parts
161in a
162.Ql \&.
163notation
164may be decimal, octal, or hexadecimal, as specified
165in the C language (i.e., a leading 0x or 0X implies
166hexadecimal; otherwise, a leading 0 implies octal;
167otherwise, the number is interpreted as decimal).
168.Sh NETWORK NUMBERS (IP VERSION 6)
169See
170.Xr inet_pton 3
171for valid external representations of IP version 6 addresses.
172A valid external representation may have
173.Dq Li /bits
174appended where
175.Dq Li bits
176is in the range
177.Li 0-128
178and is used to explicitly specify the number of bits in the network address.
179When
180.Dq Li /bits
181is not specified 128 is used.
182Note that when the number of bits is specified using
183.Dq Li /bits
184notation, the value of the address still includes all bits supplied
185in the external representation, even those bits which are the host
186part of an Internet address.
187.Sh SEE ALSO
188.Xr byteorder 3 ,
189.Xr inet 3 ,
190.Xr inet_pton 3 ,
191.Xr networks 5
192.Sh HISTORY
193The
194.Nm inet_net_ntop
195and
196.Nm inet_net_pton
197functions first appeared in BIND 4.9.4.
diff --git a/src/lib/libc/net/inet_net_ntop.c b/src/lib/libc/net/inet_net_ntop.c
new file mode 100644
index 0000000000..35ae7909d3
--- /dev/null
+++ b/src/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,162 @@
1/* $OpenBSD: inet_net_ntop.c,v 1.7 2012/06/22 19:13:37 gilles Exp $ */
2
3/*
4 * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
5 * Copyright (c) 1996 by Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
14 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
17 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
18 * SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25
26#include <errno.h>
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30
31static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t);
32static char *inet_net_ntop_ipv6(const u_char *, int, char *, size_t);
33
34/*
35 * char *
36 * inet_net_ntop(af, src, bits, dst, size)
37 * convert network number from network to presentation format.
38 * generates CIDR style result always.
39 * return:
40 * pointer to dst, or NULL if an error occurred (check errno).
41 * author:
42 * Paul Vixie (ISC), July 1996
43 */
44char *
45inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
46{
47 switch (af) {
48 case AF_INET:
49 return (inet_net_ntop_ipv4(src, bits, dst, size));
50 case AF_INET6:
51 return (inet_net_ntop_ipv6(src, bits, dst, size));
52 default:
53 errno = EAFNOSUPPORT;
54 return (NULL);
55 }
56}
57
58/*
59 * static char *
60 * inet_net_ntop_ipv4(src, bits, dst, size)
61 * convert IPv4 network number from network to presentation format.
62 * generates CIDR style result always.
63 * return:
64 * pointer to dst, or NULL if an error occurred (check errno).
65 * note:
66 * network byte order assumed. this means 192.5.5.240/28 has
67 * 0x11110000 in its fourth octet.
68 * author:
69 * Paul Vixie (ISC), July 1996
70 */
71static char *
72inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
73{
74 char *odst = dst;
75 u_int m;
76 int b;
77 char *ep;
78 int advance;
79
80 ep = dst + size;
81 if (ep <= dst)
82 goto emsgsize;
83
84 if (bits < 0 || bits > 32) {
85 errno = EINVAL;
86 return (NULL);
87 }
88 if (bits == 0) {
89 if (ep - dst < sizeof "0")
90 goto emsgsize;
91 *dst++ = '0';
92 *dst = '\0';
93 }
94
95 /* Format whole octets. */
96 for (b = bits / 8; b > 0; b--) {
97 if (ep - dst < sizeof "255.")
98 goto emsgsize;
99 advance = snprintf(dst, ep - dst, "%u", *src++);
100 if (advance <= 0 || advance >= ep - dst)
101 goto emsgsize;
102 dst += advance;
103 if (b > 1) {
104 if (dst + 1 >= ep)
105 goto emsgsize;
106 *dst++ = '.';
107 *dst = '\0';
108 }
109 }
110
111 /* Format partial octet. */
112 b = bits % 8;
113 if (b > 0) {
114 if (ep - dst < sizeof ".255")
115 goto emsgsize;
116 if (dst != odst)
117 if (dst + 1 >= ep)
118 goto emsgsize;
119 *dst++ = '.';
120 m = ((1 << b) - 1) << (8 - b);
121 advance = snprintf(dst, ep - dst, "%u", *src & m);
122 if (advance <= 0 || advance >= ep - dst)
123 goto emsgsize;
124 dst += advance;
125 }
126
127 /* Format CIDR /width. */
128 if (ep - dst < sizeof "/32")
129 goto emsgsize;
130 advance = snprintf(dst, ep - dst, "/%u", bits);
131 if (advance <= 0 || advance >= ep - dst)
132 goto emsgsize;
133 dst += advance;
134 return (odst);
135
136 emsgsize:
137 errno = EMSGSIZE;
138 return (NULL);
139}
140
141static char *
142inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
143{
144 int ret;
145 char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];
146
147 if (bits < 0 || bits > 128) {
148 errno = EINVAL;
149 return (NULL);
150 }
151
152 if (inet_ntop(AF_INET6, src, buf, size) == NULL)
153 return (NULL);
154
155 ret = snprintf(dst, size, "%s/%d", buf, bits);
156 if (ret == -1 || ret >= size) {
157 errno = EMSGSIZE;
158 return (NULL);
159 }
160
161 return (dst);
162}
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c
new file mode 100644
index 0000000000..1683a79043
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,231 @@
1/* $OpenBSD: inet_net_pton.c,v 1.8 2013/11/25 18:23:51 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org>
5 * Copyright (c) 1996 by Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
13 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
14 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
17 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
18 * SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25
26#include <assert.h>
27#include <ctype.h>
28#include <errno.h>
29#include <stdio.h>
30#include <string.h>
31#include <stdlib.h>
32
33static int inet_net_pton_ipv4(const char *, u_char *, size_t);
34static int inet_net_pton_ipv6(const char *, u_char *, size_t);
35
36/*
37 * static int
38 * inet_net_pton(af, src, dst, size)
39 * convert network number from presentation to network format.
40 * accepts hex octets, hex strings, decimal octets, and /CIDR.
41 * "size" is in bytes and describes "dst".
42 * return:
43 * number of bits, either imputed classfully or specified with /CIDR,
44 * or -1 if some failure occurred (check errno). ENOENT means it was
45 * not a valid network specification.
46 * author:
47 * Paul Vixie (ISC), June 1996
48 */
49int
50inet_net_pton(int af, const char *src, void *dst, size_t size)
51{
52 switch (af) {
53 case AF_INET:
54 return (inet_net_pton_ipv4(src, dst, size));
55 case AF_INET6:
56 return (inet_net_pton_ipv6(src, dst, size));
57 default:
58 errno = EAFNOSUPPORT;
59 return (-1);
60 }
61}
62
63/*
64 * static int
65 * inet_net_pton_ipv4(src, dst, size)
66 * convert IPv4 network number from presentation to network format.
67 * accepts hex octets, hex strings, decimal octets, and /CIDR.
68 * "size" is in bytes and describes "dst".
69 * return:
70 * number of bits, either imputed classfully or specified with /CIDR,
71 * or -1 if some failure occurred (check errno). ENOENT means it was
72 * not an IPv4 network specification.
73 * note:
74 * network byte order assumed. this means 192.5.5.240/28 has
75 * 0x11110000 in its fourth octet.
76 * author:
77 * Paul Vixie (ISC), June 1996
78 */
79static int
80inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
81{
82 static const char
83 xdigits[] = "0123456789abcdef",
84 digits[] = "0123456789";
85 int n, ch, tmp, dirty, bits;
86 const u_char *odst = dst;
87
88 ch = (unsigned char)*src++;
89 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
90 && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) {
91 /* Hexadecimal: Eat nybble string. */
92 if (size <= 0)
93 goto emsgsize;
94 *dst = 0, dirty = 0;
95 src++; /* skip x or X. */
96 while ((ch = (unsigned char)*src++) != '\0' &&
97 isascii(ch) && isxdigit(ch)) {
98 if (isupper(ch))
99 ch = tolower(ch);
100 n = strchr(xdigits, ch) - xdigits;
101 assert(n >= 0 && n <= 15);
102 *dst |= n;
103 if (!dirty++)
104 *dst <<= 4;
105 else if (size-- > 0)
106 *++dst = 0, dirty = 0;
107 else
108 goto emsgsize;
109 }
110 if (dirty)
111 size--;
112 } else if (isascii(ch) && isdigit(ch)) {
113 /* Decimal: eat dotted digit string. */
114 for (;;) {
115 tmp = 0;
116 do {
117 n = strchr(digits, ch) - digits;
118 assert(n >= 0 && n <= 9);
119 tmp *= 10;
120 tmp += n;
121 if (tmp > 255)
122 goto enoent;
123 } while ((ch = (unsigned char)*src++) != '\0' &&
124 isascii(ch) && isdigit(ch));
125 if (size-- <= 0)
126 goto emsgsize;
127 *dst++ = (u_char) tmp;
128 if (ch == '\0' || ch == '/')
129 break;
130 if (ch != '.')
131 goto enoent;
132 ch = (unsigned char)*src++;
133 if (!isascii(ch) || !isdigit(ch))
134 goto enoent;
135 }
136 } else
137 goto enoent;
138
139 bits = -1;
140 if (ch == '/' && isascii((unsigned char)src[0]) &&
141 isdigit((unsigned char)src[0]) && dst > odst) {
142 /* CIDR width specifier. Nothing can follow it. */
143 ch = (unsigned char)*src++; /* Skip over the /. */
144 bits = 0;
145 do {
146 n = strchr(digits, ch) - digits;
147 assert(n >= 0 && n <= 9);
148 bits *= 10;
149 bits += n;
150 if (bits > 32)
151 goto emsgsize;
152 } while ((ch = (unsigned char)*src++) != '\0' &&
153 isascii(ch) && isdigit(ch));
154 if (ch != '\0')
155 goto enoent;
156 }
157
158 /* Firey death and destruction unless we prefetched EOS. */
159 if (ch != '\0')
160 goto enoent;
161
162 /* If nothing was written to the destination, we found no address. */
163 if (dst == odst)
164 goto enoent;
165 /* If no CIDR spec was given, infer width from net class. */
166 if (bits == -1) {
167 if (*odst >= 240) /* Class E */
168 bits = 32;
169 else if (*odst >= 224) /* Class D */
170 bits = 4;
171 else if (*odst >= 192) /* Class C */
172 bits = 24;
173 else if (*odst >= 128) /* Class B */
174 bits = 16;
175 else /* Class A */
176 bits = 8;
177 /* If imputed mask is narrower than specified octets, widen. */
178 if (bits < ((dst - odst) * 8))
179 bits = (dst - odst) * 8;
180 }
181 /* Extend network to cover the actual mask. */
182 while (bits > ((dst - odst) * 8)) {
183 if (size-- <= 0)
184 goto emsgsize;
185 *dst++ = '\0';
186 }
187 return (bits);
188
189 enoent:
190 errno = ENOENT;
191 return (-1);
192
193 emsgsize:
194 errno = EMSGSIZE;
195 return (-1);
196}
197
198
199static int
200inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
201{
202 int ret;
203 int bits;
204 char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")];
205 char *sep;
206 const char *errstr;
207
208 if (strlcpy(buf, src, sizeof buf) >= sizeof buf) {
209 errno = EMSGSIZE;
210 return (-1);
211 }
212
213 sep = strchr(buf, '/');
214 if (sep != NULL)
215 *sep++ = '\0';
216
217 ret = inet_pton(AF_INET6, buf, dst);
218 if (ret != 1)
219 return (-1);
220
221 if (sep == NULL)
222 return 128;
223
224 bits = strtonum(sep, 0, 128, &errstr);
225 if (errstr) {
226 errno = EINVAL;
227 return (-1);
228 }
229
230 return bits;
231}
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000000..e3e7d0eb71
--- /dev/null
+++ b/src/lib/libc/net/inet_neta.c
@@ -0,0 +1,80 @@
1/* $OpenBSD: inet_neta.c,v 1.7 2005/08/06 20:30:03 espie Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24
25#include <errno.h>
26#include <stdio.h>
27#include <string.h>
28
29/*
30 * char *
31 * inet_neta(src, dst, size)
32 * format an in_addr_t network number into presentation format.
33 * return:
34 * pointer to dst, or NULL if an error occurred (check errno).
35 * note:
36 * format of ``src'' is as for inet_network().
37 * author:
38 * Paul Vixie (ISC), July 1996
39 */
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
new file mode 100644
index 0000000000..2f468c3aca
--- /dev/null
+++ b/src/lib/libc/net/inet_netof.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: inet_netof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/param.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34
35/*
36 * Return the network number from an internet
37 * address; handles class a/b/c network #'s.
38 */
39in_addr_t
40inet_netof(struct in_addr in)
41{
42 in_addr_t i = ntohl(in.s_addr);
43
44 if (IN_CLASSA(i))
45 return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
46 else if (IN_CLASSB(i))
47 return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
48 else
49 return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
50}
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c
new file mode 100644
index 0000000000..ecf554e4f9
--- /dev/null
+++ b/src/lib/libc/net/inet_network.c
@@ -0,0 +1,84 @@
1/* $OpenBSD: inet_network.c,v 1.11 2013/11/25 17:29:19 deraadt Exp $ */
2/*
3 * Copyright (c) 1983, 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
31#include <sys/types.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <ctype.h>
35
36/*
37 * Internet network address interpretation routine.
38 * The library routines call this routine to interpret
39 * network numbers.
40 */
41in_addr_t
42inet_network(const char *cp)
43{
44 in_addr_t val, base, n;
45 u_char c;
46 in_addr_t parts[4], *pp = parts;
47 int i;
48
49again:
50 val = 0; base = 10;
51 if (*cp == '0')
52 base = 8, cp++;
53 if (*cp == 'x' || *cp == 'X')
54 base = 16, cp++;
55 while ((c = *cp)) {
56 if (isdigit(c)) {
57 val = (val * base) + (c - '0');
58 cp++;
59 continue;
60 }
61 if (base == 16 && isxdigit(c)) {
62 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
63 cp++;
64 continue;
65 }
66 break;
67 }
68 if (*cp == '.') {
69 if (pp >= parts + 3)
70 return (INADDR_NONE);
71 *pp++ = val, cp++;
72 goto again;
73 }
74 if (*cp && !isspace(*cp))
75 return (INADDR_NONE);
76 *pp++ = val;
77 n = pp - parts;
78 for (val = 0, i = 0; i < 4; i++) {
79 val <<= 8;
80 if (i < n)
81 val |= parts[i] & 0xff;
82 }
83 return (val);
84}
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c
new file mode 100644
index 0000000000..ff5d93ded2
--- /dev/null
+++ b/src/lib/libc/net/inet_ntoa.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: inet_ntoa.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1983, 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
31/*
32 * Convert network-format internet address
33 * to base 256 d.d.d.d representation.
34 */
35#include <sys/types.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <stdio.h>
39
40char *
41inet_ntoa(struct in_addr in)
42{
43 static char b[18];
44 char *p;
45
46 p = (char *)&in;
47#define UC(b) (((int)b)&0xff)
48 (void)snprintf(b, sizeof(b),
49 "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
50 return (b);
51}
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000000..359acd8cda
--- /dev/null
+++ b/src/lib/libc/net/inet_ntop.c
@@ -0,0 +1,205 @@
1/* $OpenBSD: inet_ntop.c,v 1.9 2014/02/05 14:20:43 millert Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <arpa/nameser.h>
25#include <string.h>
26#include <errno.h>
27#include <stdio.h>
28
29/*
30 * WARNING: Don't even consider trying to compile this on a system where
31 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
32 */
33
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/* const char *
38 * inet_ntop(af, src, dst, size)
39 * convert a network format address to presentation format.
40 * return:
41 * pointer to presentation format address (`dst'), or NULL (see errno).
42 * author:
43 * Paul Vixie, 1996.
44 */
45const char *
46inet_ntop(int af, const void *src, char *dst, socklen_t size)
47{
48 switch (af) {
49 case AF_INET:
50 return (inet_ntop4(src, dst, (size_t)size));
51 case AF_INET6:
52 return (inet_ntop6(src, dst, (size_t)size));
53 default:
54 errno = EAFNOSUPPORT;
55 return (NULL);
56 }
57 /* NOTREACHED */
58}
59
60/* const char *
61 * inet_ntop4(src, dst, size)
62 * format an IPv4 address, more or less like inet_ntoa()
63 * return:
64 * `dst' (as a const)
65 * notes:
66 * (1) uses no statics
67 * (2) takes a u_char* not an in_addr as input
68 * author:
69 * Paul Vixie, 1996.
70 */
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 errno = ENOSPC;
153 return (NULL);
154 }
155 *tp++ = ':';
156 }
157 continue;
158 }
159 /* Are we following an initial run of 0x00s or any real hex? */
160 if (i != 0) {
161 if (tp + 1 >= ep) {
162 errno = ENOSPC;
163 return (NULL);
164 }
165 *tp++ = ':';
166 }
167 /* Is this address an encapsulated IPv4? */
168 if (i == 6 && best.base == 0 &&
169 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
170 if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
171 return (NULL);
172 tp += strlen(tp);
173 break;
174 }
175 advance = snprintf(tp, ep - tp, "%x", words[i]);
176 if (advance <= 0 || advance >= ep - tp) {
177 errno = ENOSPC;
178 return (NULL);
179 }
180 tp += advance;
181 }
182 /* Was it a trailing run of 0x00's? */
183 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
184 if (tp + 1 >= ep) {
185 errno = ENOSPC;
186 return (NULL);
187 }
188 *tp++ = ':';
189 }
190 if (tp + 1 >= ep) {
191 errno = ENOSPC;
192 return (NULL);
193 }
194 *tp++ = '\0';
195
196 /*
197 * Check for overflow, copy, and we're done.
198 */
199 if ((size_t)(tp - tmp) > size) {
200 errno = ENOSPC;
201 return (NULL);
202 }
203 strlcpy(dst, tmp, size);
204 return (dst);
205}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..7e521c3286
--- /dev/null
+++ b/src/lib/libc/net/inet_pton.c
@@ -0,0 +1,213 @@
1/* $OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <arpa/nameser.h>
25#include <string.h>
26#include <errno.h>
27
28/*
29 * WARNING: Don't even consider trying to compile this on a system where
30 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
31 */
32
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 * does not touch `dst' unless it's returning 1.
118 * credit:
119 * inspired by Mark Andrews.
120 * author:
121 * Paul Vixie, 1996.
122 */
123static int
124inet_pton6(const char *src, u_char *dst)
125{
126 static const char xdigits_l[] = "0123456789abcdef",
127 xdigits_u[] = "0123456789ABCDEF";
128 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
129 const char *xdigits, *curtok;
130 int ch, saw_xdigit, count_xdigit;
131 u_int val;
132
133 memset((tp = tmp), '\0', IN6ADDRSZ);
134 endp = tp + IN6ADDRSZ;
135 colonp = NULL;
136 /* Leading :: requires some special handling. */
137 if (*src == ':')
138 if (*++src != ':')
139 return (0);
140 curtok = src;
141 saw_xdigit = count_xdigit = 0;
142 val = 0;
143 while ((ch = *src++) != '\0') {
144 const char *pch;
145
146 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
147 pch = strchr((xdigits = xdigits_u), ch);
148 if (pch != NULL) {
149 if (count_xdigit >= 4)
150 return (0);
151 val <<= 4;
152 val |= (pch - xdigits);
153 if (val > 0xffff)
154 return (0);
155 saw_xdigit = 1;
156 count_xdigit++;
157 continue;
158 }
159 if (ch == ':') {
160 curtok = src;
161 if (!saw_xdigit) {
162 if (colonp)
163 return (0);
164 colonp = tp;
165 continue;
166 } else if (*src == '\0') {
167 return (0);
168 }
169 if (tp + INT16SZ > endp)
170 return (0);
171 *tp++ = (u_char) (val >> 8) & 0xff;
172 *tp++ = (u_char) val & 0xff;
173 saw_xdigit = 0;
174 count_xdigit = 0;
175 val = 0;
176 continue;
177 }
178 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
179 inet_pton4(curtok, tp) > 0) {
180 tp += INADDRSZ;
181 saw_xdigit = 0;
182 count_xdigit = 0;
183 break; /* '\0' was seen by inet_pton4(). */
184 }
185 return (0);
186 }
187 if (saw_xdigit) {
188 if (tp + INT16SZ > endp)
189 return (0);
190 *tp++ = (u_char) (val >> 8) & 0xff;
191 *tp++ = (u_char) val & 0xff;
192 }
193 if (colonp != NULL) {
194 /*
195 * Since some memmove()'s erroneously fail to handle
196 * overlapping regions, we'll do the shift by hand.
197 */
198 const int n = tp - colonp;
199 int i;
200
201 if (tp == endp)
202 return (0);
203 for (i = 1; i <= n; i++) {
204 endp[- i] = colonp[n - i];
205 colonp[n - i] = 0;
206 }
207 tp = endp;
208 }
209 if (tp != endp)
210 return (0);
211 memcpy(dst, tmp, IN6ADDRSZ);
212 return (1);
213}
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c
new file mode 100644
index 0000000000..7b4fdc4c4e
--- /dev/null
+++ b/src/lib/libc/net/ip6opt.c
@@ -0,0 +1,593 @@
1/* $OpenBSD: ip6opt.c,v 1.6 2014/02/17 21:05:39 stsp Exp $ */
2/* $KAME: ip6opt.c,v 1.18 2005/06/15 07:11:35 keiichi Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/socket.h>
36
37#include <netinet/in.h>
38#include <netinet/ip6.h>
39
40#include <string.h>
41#include <stdio.h>
42
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 (ext) {
387 if (extlen <= 0 || (extlen % 8))
388 return (-1);
389 ext->ip6e_len = (extlen >> 3) - 1;
390 }
391
392 return (2); /* sizeof the next and the length fields */
393}
394
395int
396inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
397 socklen_t len, u_int8_t align, void **databufp)
398{
399 int currentlen = offset, padlen = 0;
400
401 /*
402 * The option type must have a value from 2 to 255, inclusive.
403 * (0 and 1 are reserved for the Pad1 and PadN options, respectively.)
404 */
405#if 0 /* always false */
406 if (type < 2 || type > 255)
407#else
408 if (type < 2)
409#endif
410 return (-1);
411
412 /*
413 * The option data length must have a value between 0 and 255,
414 * inclusive, and is the length of the option data that follows.
415 */
416 if (len < 0 || len > 255)
417 return (-1);
418
419 /*
420 * The align parameter must have a value of 1, 2, 4, or 8.
421 * The align value can not exceed the value of len.
422 */
423 if (align != 1 && align != 2 && align != 4 && align != 8)
424 return (-1);
425 if (align > len)
426 return (-1);
427
428 /* Calculate the padding length. */
429 currentlen += 2 + len; /* 2 means "type + len" */
430 if (currentlen % align)
431 padlen = align - (currentlen % align);
432
433 /* The option must fit in the extension header buffer. */
434 currentlen += padlen;
435 if (extlen && /* XXX: right? */
436 currentlen > extlen)
437 return (-1);
438
439 if (extbuf) {
440 u_int8_t *optp = (u_int8_t *)extbuf + offset;
441
442 if (padlen == 1) {
443 /* insert a Pad1 option */
444 *optp = IP6OPT_PAD1;
445 optp++;
446 } else if (padlen > 0) {
447 /* insert a PadN option for alignment */
448 *optp++ = IP6OPT_PADN;
449 *optp++ = padlen - 2;
450 memset(optp, 0, padlen - 2);
451 optp += (padlen - 2);
452 }
453
454 *optp++ = type;
455 *optp++ = len;
456
457 *databufp = optp;
458 }
459
460 return (currentlen);
461}
462
463int
464inet6_opt_finish(void *extbuf, socklen_t extlen, int offset)
465{
466 int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0;;
467
468 if (extbuf) {
469 u_int8_t *padp;
470 int padlen = updatelen - offset;
471
472 if (updatelen > extlen)
473 return (-1);
474
475 padp = (u_int8_t *)extbuf + offset;
476 if (padlen == 1)
477 *padp = IP6OPT_PAD1;
478 else if (padlen > 0) {
479 *padp++ = IP6OPT_PADN;
480 *padp++ = (padlen - 2);
481 memset(padp, 0, padlen - 2);
482 }
483 }
484
485 return (updatelen);
486}
487
488int
489inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen)
490{
491
492 memcpy((u_int8_t *)databuf + offset, val, vallen);
493 return (offset + vallen);
494}
495
496int
497inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep,
498 socklen_t *lenp, void **databufp)
499{
500 u_int8_t *optp, *lim;
501 int optlen;
502
503 /* Validate extlen. XXX: is the variable really necessary?? */
504 if (extlen == 0 || (extlen % 8))
505 return (-1);
506 lim = (u_int8_t *)extbuf + extlen;
507
508 /*
509 * If this is the first time this function called for this options
510 * header, simply return the 1st option.
511 * Otherwise, search the option list for the next option.
512 */
513 if (offset == 0)
514 optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
515 else
516 optp = (u_int8_t *)extbuf + offset;
517
518 /* Find the next option skipping any padding options. */
519 while (optp < lim) {
520 switch(*optp) {
521 case IP6OPT_PAD1:
522 optp++;
523 break;
524 case IP6OPT_PADN:
525 if ((optlen = ip6optlen(optp, lim)) == 0)
526 goto optend;
527 optp += optlen;
528 break;
529 default: /* found */
530 if ((optlen = ip6optlen(optp, lim)) == 0)
531 goto optend;
532 *typep = *optp;
533 *lenp = optlen - 2;
534 *databufp = optp + 2;
535 return (optp + optlen - (u_int8_t *)extbuf);
536 }
537 }
538
539 optend:
540 *databufp = NULL; /* for safety */
541 return (-1);
542}
543
544int
545inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
546 socklen_t *lenp, void **databufp)
547{
548 u_int8_t *optp, *lim;
549 int optlen;
550
551 /* Validate extlen. XXX: is the variable really necessary?? */
552 if (extlen == 0 || (extlen % 8))
553 return (-1);
554 lim = (u_int8_t *)extbuf + extlen;
555
556 /*
557 * If this is the first time this function called for this options
558 * header, simply return the 1st option.
559 * Otherwise, search the option list for the next option.
560 */
561 if (offset == 0)
562 optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
563 else
564 optp = (u_int8_t *)extbuf + offset;
565
566 /* Find the specified option */
567 while (optp < lim) {
568 if ((optlen = ip6optlen(optp, lim)) == 0)
569 goto optend;
570
571 if (*optp == type) { /* found */
572 *lenp = optlen - 2;
573 *databufp = optp + 2;
574 return (optp + optlen - (u_int8_t *)extbuf);
575 }
576
577 optp += optlen;
578 }
579
580 optend:
581 *databufp = NULL; /* for safety */
582 return (-1);
583}
584
585int
586inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen)
587{
588
589 /* we can't assume alignment here */
590 memcpy(val, (u_int8_t *)databuf + offset, vallen);
591
592 return (offset + vallen);
593}
diff --git a/src/lib/libc/net/link_addr.3 b/src/lib/libc/net/link_addr.3
new file mode 100644
index 0000000000..f234fe84cc
--- /dev/null
+++ b/src/lib/libc/net/link_addr.3
@@ -0,0 +1,127 @@
1.\" $OpenBSD: link_addr.3,v 1.13 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Donn Seeley at BSDI.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. Neither 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.Dd $Mdocdate: June 5 2013 $
34.Dt LINK_ADDR 3
35.Os
36.Sh NAME
37.Nm link_addr ,
38.Nm link_ntoa
39.Nd elementary address specification routines for link level access
40.Sh SYNOPSIS
41.In sys/types.h
42.In sys/socket.h
43.In net/if_dl.h
44.Ft void
45.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
46.Ft char *
47.Fn link_ntoa "const struct sockaddr_dl *sdl"
48.Sh DESCRIPTION
49The
50.Fn link_addr
51function interprets character strings representing
52link-level addresses, returning binary information suitable
53for use in system calls.
54.Fn link_ntoa
55takes
56a link-level
57address and returns an
58.Tn ASCII
59string representing some of the information present,
60including the link level address itself, and the interface name
61or number, if present.
62This facility is experimental and is
63still subject to change.
64.Pp
65For
66.Fn link_addr ,
67the string
68.Fa addr
69may contain
70an optional network interface identifier of the form
71.Dq name unit-number ,
72suitable for the first argument to
73.Xr ifconfig 8 ,
74followed in all cases by a colon and
75an interface address in the form of
76groups of hexadecimal digits
77separated by periods.
78Each group represents a byte of address;
79address bytes are filled left to right from
80low order bytes through high order bytes.
81.Pp
82.\" A regular expression may make this format clearer:
83.\" .Bd -literal -offset indent
84.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
85.\" .Ed
86.\" .Pp
87Thus
88.Li le0:8.0.9.13.d.30
89represents an Ethernet address
90to be transmitted on the first Lance Ethernet interface.
91.Sh RETURN VALUES
92.Fn link_ntoa
93always returns a NUL-terminated string.
94.Fn link_addr
95has no return value.
96(See
97.Sx BUGS . )
98.Sh SEE ALSO
99.Xr ifconfig 8
100.Sh HISTORY
101The
102.Fn link_addr
103and
104.Fn link_ntoa
105functions appeared in
106.Bx 4.3 Reno .
107.Sh BUGS
108The returned values for
109.Fn link_ntoa
110reside in a static memory area.
111.Pp
112The function
113.Fn link_addr
114should diagnose improperly formed input, and there should be an unambiguous
115way to recognize this.
116.Pp
117If the
118.Fa sdl_len
119field of the link socket address
120.Fa sdl
121is 0,
122.Fn link_ntoa
123will not insert a colon before the interface address bytes.
124If this translated address is given to
125.Fn link_addr
126without inserting an initial colon,
127the latter will not interpret it correctly.
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c
new file mode 100644
index 0000000000..ac96f3acdf
--- /dev/null
+++ b/src/lib/libc/net/linkaddr.c
@@ -0,0 +1,148 @@
1/* $OpenBSD: linkaddr.c,v 1.5 2005/08/06 20:30:03 espie Exp $ */
2/*-
3 * Copyright (c) 1990, 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
31#include <sys/types.h>
32#include <sys/socket.h>
33#include <net/if_dl.h>
34#include <string.h>
35
36/* States*/
37#define NAMING 0
38#define GOTONE 1
39#define GOTTWO 2
40#define RESET 3
41/* Inputs */
42#define DIGIT (4*0)
43#define END (4*1)
44#define DELIM (4*2)
45#define LETTER (4*3)
46
47void
48link_addr(const char *addr, struct sockaddr_dl *sdl)
49{
50 char *cp = sdl->sdl_data;
51 char *cplim = sdl->sdl_len + (char *)sdl;
52 int byte = 0, state = NAMING, new;
53
54 bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
55 sdl->sdl_family = AF_LINK;
56 do {
57 state &= ~LETTER;
58 if ((*addr >= '0') && (*addr <= '9')) {
59 new = *addr - '0';
60 } else if ((*addr >= 'a') && (*addr <= 'f')) {
61 new = *addr - 'a' + 10;
62 } else if ((*addr >= 'A') && (*addr <= 'F')) {
63 new = *addr - 'A' + 10;
64 } else if (*addr == 0) {
65 state |= END;
66 } else if (state == NAMING &&
67 (((*addr >= 'A') && (*addr <= 'Z')) ||
68 ((*addr >= 'a') && (*addr <= 'z'))))
69 state |= LETTER;
70 else
71 state |= DELIM;
72 addr++;
73 switch (state /* | INPUT */) {
74 case NAMING | DIGIT:
75 case NAMING | LETTER:
76 *cp++ = addr[-1];
77 continue;
78 case NAMING | DELIM:
79 state = RESET;
80 sdl->sdl_nlen = cp - sdl->sdl_data;
81 continue;
82 case GOTTWO | DIGIT:
83 *cp++ = byte;
84 /* FALLTHROUGH */
85 case RESET | DIGIT:
86 state = GOTONE;
87 byte = new;
88 continue;
89 case GOTONE | DIGIT:
90 state = GOTTWO;
91 byte = new + (byte << 4);
92 continue;
93 default: /* | DELIM */
94 state = RESET;
95 *cp++ = byte;
96 byte = 0;
97 continue;
98 case GOTONE | END:
99 case GOTTWO | END:
100 *cp++ = byte;
101 /* FALLTHROUGH */
102 case RESET | END:
103 break;
104 }
105 break;
106 } while (cp < cplim);
107 sdl->sdl_alen = cp - LLADDR(sdl);
108 new = cp - (char *)sdl;
109 if (new > sizeof(*sdl))
110 sdl->sdl_len = new;
111 return;
112}
113
114static char hexlist[] = "0123456789abcdef";
115
116char *
117link_ntoa(const struct sockaddr_dl *sdl)
118{
119 static char obuf[64];
120 char *out = obuf;
121 int i;
122 u_char *in = (u_char *)LLADDR(sdl);
123 u_char *inlim = in + sdl->sdl_alen;
124 int firsttime = 1;
125
126 if (sdl->sdl_nlen) {
127 bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
128 out += sdl->sdl_nlen;
129 if (sdl->sdl_alen)
130 *out++ = ':';
131 }
132 while (in < inlim) {
133 if (firsttime)
134 firsttime = 0;
135 else
136 *out++ = '.';
137 i = *in++;
138 if (i > 0xf) {
139 out[1] = hexlist[i & 0xf];
140 i >>= 4;
141 out[0] = hexlist[i];
142 out += 2;
143 } else
144 *out++ = hexlist[i];
145 }
146 *out = 0;
147 return (obuf);
148}
diff --git a/src/lib/libc/net/ntohl.c b/src/lib/libc/net/ntohl.c
new file mode 100644
index 0000000000..36414b7a13
--- /dev/null
+++ b/src/lib/libc/net/ntohl.c
@@ -0,0 +1,21 @@
1/* $OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <sys/types.h>
8#include <machine/endian.h>
9
10#undef ntohl
11
12u_int32_t
13ntohl(u_int32_t x)
14{
15#if BYTE_ORDER == LITTLE_ENDIAN
16 u_char *s = (u_char *)&x;
17 return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
18#else
19 return x;
20#endif
21}
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c
new file mode 100644
index 0000000000..8f345e84ad
--- /dev/null
+++ b/src/lib/libc/net/ntohs.c
@@ -0,0 +1,21 @@
1/* $OpenBSD: ntohs.c,v 1.8 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <sys/types.h>
8#include <machine/endian.h>
9
10#undef ntohs
11
12u_int16_t
13ntohs(u_int16_t x)
14{
15#if BYTE_ORDER == LITTLE_ENDIAN
16 u_char *s = (u_char *) &x;
17 return (u_int16_t)(s[0] << 8 | s[1]);
18#else
19 return x;
20#endif
21}
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3
new file mode 100644
index 0000000000..447aa23ff1
--- /dev/null
+++ b/src/lib/libc/net/rcmd.3
@@ -0,0 +1,266 @@
1.\" $OpenBSD: rcmd.3,v 1.29 2014/01/21 03:15:45 schwarze 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: January 21 2014 $
31.Dt RCMD 3
32.Os
33.Sh NAME
34.Nm rcmd ,
35.Nm rcmd_af ,
36.Nm rresvport ,
37.Nm rresvport_af ,
38.Nm iruserok ,
39.Nm ruserok ,
40.Nm iruserok_sa
41.Nd routines for returning a stream to a remote command
42.Sh SYNOPSIS
43.In unistd.h
44.Ft int
45.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
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
49.Fn rresvport "int *port"
50.Ft int
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"
54.Ft int
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"
58.Sh DESCRIPTION
59The
60.Fn rcmd
61function is used by the superuser to execute a command on a remote
62machine using an authentication scheme based on reserved
63port 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
86The
87.Fn rresvport
88and
89.Fn rresvport_af
90functions return a descriptor to a socket
91with an address in the privileged port space.
92The
93.Fn iruserok
94and
95.Fn ruserok
96functions are used by servers
97to authenticate clients requesting service with
98.Fn rcmd .
99All four functions are present in the same file and are used
100by the
101.Xr rshd 8
102server (among others).
103.Fn iruserok_sa
104is an address family independent variant of
105.Fn iruserok .
106.Pp
107The
108.Fn rcmd
109function looks up the host
110.Fa *ahost
111using
112.Xr gethostbyname 3 ,
113returning \-1 if the host does not exist.
114Otherwise
115.Fa *ahost
116is set to the standard name of the host
117and a connection is established to a server
118residing at the well-known Internet port
119.Fa inport .
120If the user is not the superuser, the only valid port is
121.Dq shell/tcp
122(usually port 514).
123.Pp
124If the connection succeeds,
125a socket in the Internet domain of type
126.Dv SOCK_STREAM
127is returned to the caller, and given to the remote
128command as stdin and stdout.
129If
130.Fa fd2p
131is non-zero, then an auxiliary channel to a control
132process will be set up, and a descriptor for it will be placed
133in
134.Fa *fd2p .
135The control process will return diagnostic
136output from the command (unit 2) on this channel, and will also
137accept bytes on this channel as being
138.Tn UNIX
139signal numbers, to be
140forwarded to the process group of the command.
141If
142.Fa fd2p
143is
144.Va NULL ,
145then the standard error (unit 2 of the remote command) will be made
146the same as the standard output and no provision is made for sending
147arbitrary signals to the remote process, although you may be able to
148get its attention by using out-of-band data.
149Note that if the user is not the superuser,
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.
161.Pp
162The protocol is described in detail in
163.Xr rshd 8 .
164.Pp
165The
166.Fn rresvport
167and
168.Fn rresvport_af
169functions are used to obtain a socket with a privileged
170address bound to it.
171This socket is suitable for use by
172.Fn rcmd
173and several other functions.
174Privileged Internet ports are those in the range 0 to
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.
183.Pp
184The
185.Fn iruserok
186and
187.Fn ruserok
188functions take a remote host's IP address or name, respectively,
189two user names and a flag indicating whether the local user's
190name is that of the superuser.
191Then, if the user is
192.Em not
193the superuser, it checks the
194.Pa /etc/hosts.equiv
195file.
196If that lookup is not done, or is unsuccessful, the
197.Pa .rhosts
198in the local user's home directory is checked to see if the request for
199service is allowed.
200.Pp
201If this file does not exist, is not a regular file, is owned by anyone
202other than the user or the superuser, or is writeable by anyone other
203than the owner, the check automatically fails.
204Zero is returned if the machine name is listed in the
205.Pa hosts.equiv
206file, or the host and remote user name are found in the
207.Pa .rhosts
208file; otherwise
209.Fn iruserok
210and
211.Fn ruserok
212return \-1.
213If the local domain (as obtained from
214.Xr gethostname 3 )
215is the same as the remote domain, only the machine name need be specified.
216.Pp
217If the IP address of the remote host is known,
218.Fn iruserok
219should be used in preference to
220.Fn ruserok ,
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.In unistd.h
236and
237.In sys/socket.h .
238.Sh DIAGNOSTICS
239The
240.Fn rcmd
241function returns a valid socket descriptor on success.
242It returns \-1 on error and prints a diagnostic message on the standard error.
243.Pp
244The
245.Fn rresvport
246and
247.Fn rresvport_af
248functions return a valid, bound socket descriptor on success.
249It returns \-1 on error with the global value
250.Va errno
251set according to the reason for failure.
252The error code
253.Er EAGAIN
254is overloaded to mean
255.Dq all network ports in use .
256.Sh SEE ALSO
257.Xr rsh 1 ,
258.Xr intro 2 ,
259.Xr bindresvport 3 ,
260.Xr bindresvport_sa 3 ,
261.Xr rcmdsh 3 ,
262.Xr rshd 8
263.Sh HISTORY
264These
265functions appeared in
266.Bx 4.2 .
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c
new file mode 100644
index 0000000000..d566e0ca4c
--- /dev/null
+++ b/src/lib/libc/net/rcmd.c
@@ -0,0 +1,303 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/param.h>
32#include <sys/socket.h>
33#include <sys/stat.h>
34
35#include <netinet/in.h>
36#include <arpa/inet.h>
37
38#include <signal.h>
39#include <fcntl.h>
40#include <netdb.h>
41#include <unistd.h>
42#include <pwd.h>
43#include <errno.h>
44#include <stdio.h>
45#include <ctype.h>
46#include <string.h>
47#include <syslog.h>
48#include <stdlib.h>
49
50int
51rcmd(char **ahost, int rport, const char *locuser, const char *remuser,
52 const char *cmd, int *fd2p)
53{
54 return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET);
55}
56
57int
58rcmd_af(char **ahost, int porta, const char *locuser, const char *remuser,
59 const char *cmd, int *fd2p, int af)
60{
61 static char hbuf[MAXHOSTNAMELEN];
62 char pbuf[NI_MAXSERV];
63 struct addrinfo hints, *res, *r;
64 int error;
65 struct sockaddr_storage from;
66 fd_set *readsp = NULL;
67 sigset_t oldmask, mask;
68 pid_t pid;
69 int s, lport, timo;
70 char c, *p;
71 int refused;
72 in_port_t rport = porta;
73
74 /* call rcmdsh() with specified remote shell if appropriate. */
75 if (!issetugid() && (p = getenv("RSH")) && *p) {
76 struct servent *sp = getservbyname("shell", "tcp");
77
78 if (sp && sp->s_port == rport)
79 return (rcmdsh(ahost, rport, locuser, remuser,
80 cmd, p));
81 }
82
83 /* use rsh(1) if non-root and remote port is shell. */
84 if (geteuid()) {
85 struct servent *sp = getservbyname("shell", "tcp");
86
87 if (sp && sp->s_port == rport)
88 return (rcmdsh(ahost, rport, locuser, remuser,
89 cmd, NULL));
90 }
91
92 pid = getpid();
93 snprintf(pbuf, sizeof(pbuf), "%u", ntohs(rport));
94 memset(&hints, 0, sizeof(hints));
95 hints.ai_family = af;
96 hints.ai_socktype = SOCK_STREAM;
97 hints.ai_flags = AI_CANONNAME;
98 error = getaddrinfo(*ahost, pbuf, &hints, &res);
99 if (error) {
100#if 0
101 warnx("%s: %s", *ahost, gai_strerror(error));
102#endif
103 return (-1);
104 }
105 if (res->ai_canonname) {
106 strlcpy(hbuf, res->ai_canonname, sizeof(hbuf));
107 *ahost = hbuf;
108 } else
109 ; /*XXX*/
110
111 r = res;
112 refused = 0;
113 sigemptyset(&mask);
114 sigaddset(&mask, SIGURG);
115 sigprocmask(SIG_BLOCK, &mask, &oldmask);
116 for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
117 s = rresvport_af(&lport, r->ai_family);
118 if (s < 0) {
119 if (errno == EAGAIN)
120 (void)fprintf(stderr,
121 "rcmd: socket: All ports in use\n");
122 else
123 (void)fprintf(stderr, "rcmd: socket: %s\n",
124 strerror(errno));
125 if (r->ai_next) {
126 r = r->ai_next;
127 continue;
128 } else {
129 sigprocmask(SIG_SETMASK, &oldmask, NULL);
130 freeaddrinfo(res);
131 return (-1);
132 }
133 }
134 fcntl(s, F_SETOWN, pid);
135 if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
136 break;
137 (void)close(s);
138 if (errno == EADDRINUSE) {
139 lport--;
140 continue;
141 }
142 if (errno == ECONNREFUSED)
143 refused++;
144 if (r->ai_next) {
145 int oerrno = errno;
146 char hbuf[NI_MAXHOST];
147 const int niflags = NI_NUMERICHOST;
148
149 hbuf[0] = '\0';
150 if (getnameinfo(r->ai_addr, r->ai_addrlen,
151 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
152 strlcpy(hbuf, "(invalid)", sizeof hbuf);
153 (void)fprintf(stderr, "connect to address %s: ", hbuf);
154 errno = oerrno;
155 perror(0);
156 r = r->ai_next;
157 hbuf[0] = '\0';
158 if (getnameinfo(r->ai_addr, r->ai_addrlen,
159 hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
160 strlcpy(hbuf, "(invalid)", sizeof hbuf);
161 (void)fprintf(stderr, "Trying %s...\n", hbuf);
162 continue;
163 }
164 if (refused && timo <= 16) {
165 (void)sleep(timo);
166 timo *= 2;
167 r = res;
168 refused = 0;
169 continue;
170 }
171 (void)fprintf(stderr, "%s: %s\n", res->ai_canonname,
172 strerror(errno));
173 sigprocmask(SIG_SETMASK, &oldmask, NULL);
174 freeaddrinfo(res);
175 return (-1);
176 }
177 /* given "af" can be PF_UNSPEC, we need the real af for "s" */
178 af = r->ai_family;
179 freeaddrinfo(res);
180#if 0
181 /*
182 * try to rresvport() to the same port. This will make rresvport()
183 * fail it's first bind, resulting in it choosing a random port.
184 */
185 lport--;
186#endif
187 if (fd2p == 0) {
188 write(s, "", 1);
189 lport = 0;
190 } else {
191 char num[8];
192 int s2 = rresvport_af(&lport, af), s3;
193 socklen_t len = sizeof(from);
194 int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask);
195
196 if (s2 < 0)
197 goto bad;
198 readsp = (fd_set *)malloc(fdssize);
199 if (readsp == NULL) {
200 close(s2);
201 goto bad;
202 }
203 listen(s2, 1);
204 (void)snprintf(num, sizeof(num), "%d", lport);
205 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
206 (void)fprintf(stderr,
207 "rcmd: write (setting up stderr): %s\n",
208 strerror(errno));
209 (void)close(s2);
210 goto bad;
211 }
212again:
213 bzero(readsp, fdssize);
214 FD_SET(s, readsp);
215 FD_SET(s2, readsp);
216 errno = 0;
217 if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 ||
218 !FD_ISSET(s2, readsp)) {
219 if (errno != 0)
220 (void)fprintf(stderr,
221 "rcmd: select (setting up stderr): %s\n",
222 strerror(errno));
223 else
224 (void)fprintf(stderr,
225 "select: protocol failure in circuit setup\n");
226 (void)close(s2);
227 goto bad;
228 }
229 s3 = accept(s2, (struct sockaddr *)&from, &len);
230 if (s3 < 0) {
231 (void)fprintf(stderr,
232 "rcmd: accept: %s\n", strerror(errno));
233 lport = 0;
234 close(s2);
235 goto bad;
236 }
237
238 /*
239 * XXX careful for ftp bounce attacks. If discovered, shut them
240 * down and check for the real auxiliary channel to connect.
241 */
242 switch (from.ss_family) {
243 case AF_INET:
244 case AF_INET6:
245 if (getnameinfo((struct sockaddr *)&from, len,
246 NULL, 0, num, sizeof(num), NI_NUMERICSERV) == 0 &&
247 atoi(num) != 20) {
248 break;
249 }
250 close(s3);
251 goto again;
252 default:
253 break;
254 }
255 (void)close(s2);
256
257 *fd2p = s3;
258 switch (from.ss_family) {
259 case AF_INET:
260 case AF_INET6:
261 if (getnameinfo((struct sockaddr *)&from, len,
262 NULL, 0, num, sizeof(num), NI_NUMERICSERV) != 0 ||
263 (atoi(num) >= IPPORT_RESERVED ||
264 atoi(num) < IPPORT_RESERVED / 2)) {
265 (void)fprintf(stderr,
266 "socket: protocol failure in circuit setup.\n");
267 goto bad2;
268 }
269 break;
270 default:
271 break;
272 }
273 }
274 (void)write(s, locuser, strlen(locuser)+1);
275 (void)write(s, remuser, strlen(remuser)+1);
276 (void)write(s, cmd, strlen(cmd)+1);
277 if (read(s, &c, 1) != 1) {
278 (void)fprintf(stderr,
279 "rcmd: %s: %s\n", *ahost, strerror(errno));
280 goto bad2;
281 }
282 if (c != 0) {
283 while (read(s, &c, 1) == 1) {
284 (void)write(STDERR_FILENO, &c, 1);
285 if (c == '\n')
286 break;
287 }
288 goto bad2;
289 }
290 sigprocmask(SIG_SETMASK, &oldmask, NULL);
291 free(readsp);
292 return (s);
293bad2:
294 if (lport)
295 (void)close(*fd2p);
296bad:
297 if (readsp)
298 free(readsp);
299 (void)close(s);
300 sigprocmask(SIG_SETMASK, &oldmask, NULL);
301 return (-1);
302}
303
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3
new file mode 100644
index 0000000000..c84a2e4d93
--- /dev/null
+++ b/src/lib/libc/net/rcmdsh.3
@@ -0,0 +1,96 @@
1.\" $OpenBSD: rcmdsh.3,v 1.14 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt RCMDSH 3
32.Os
33.Sh NAME
34.Nm rcmdsh
35.Nd return a stream to a remote command without superuser
36.Sh SYNOPSIS
37.In unistd.h
38.Ft int
39.Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog"
40.Sh DESCRIPTION
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.Ux Ns -domain
74of 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
new file mode 100644
index 0000000000..6241cc6b12
--- /dev/null
+++ b/src/lib/libc/net/recv.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: recv.c,v 1.5 2005/08/06 20:30:03 espie Exp $ */
2/*
3 * Copyright (c) 1988, 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
31#include <sys/types.h>
32#include <sys/socket.h>
33
34#include <stddef.h>
35
36ssize_t
37recv(int s, void *buf, size_t len, int flags)
38{
39 return (recvfrom(s, buf, len, flags, NULL, 0));
40}
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
new file mode 100644
index 0000000000..69a6ce0abb
--- /dev/null
+++ b/src/lib/libc/net/res_comp.c
@@ -0,0 +1,475 @@
1/* $OpenBSD: res_comp.c,v 1.14 2008/04/16 22:35:23 deraadt Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
6 * Copyright (c) 1985, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither 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 <netinet/in.h>
57#include <arpa/nameser.h>
58
59#include <stdio.h>
60#include <resolv.h>
61#include <ctype.h>
62
63#include <unistd.h>
64#include <string.h>
65
66static int dn_find(u_char *, u_char *, u_char **, u_char **);
67
68/*
69 * Expand compressed domain name 'comp_dn' to full domain name.
70 * 'msg' is a pointer to the begining of the message,
71 * 'eomorig' points to the first location after the message,
72 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
73 * Return size of compressed name or -1 if there was an error.
74 */
75int
76dn_expand(const u_char *msg, const u_char *eomorig, const u_char *comp_dn,
77 char *exp_dn, int length)
78{
79 const u_char *cp;
80 char *dn;
81 int n, c;
82 char *eom;
83 int len = -1, checked = 0;
84
85 dn = exp_dn;
86 cp = comp_dn;
87 if (length > MAXHOSTNAMELEN-1)
88 length = MAXHOSTNAMELEN-1;
89 eom = exp_dn + length;
90 /*
91 * fetch next label in domain name
92 */
93 while ((n = *cp++)) {
94 /*
95 * Check for indirection
96 */
97 switch (n & INDIR_MASK) {
98 case 0:
99 if (dn != exp_dn) {
100 if (dn >= eom)
101 return (-1);
102 *dn++ = '.';
103 }
104 if (dn+n >= eom)
105 return (-1);
106 checked += n + 1;
107 while (--n >= 0) {
108 if (((c = *cp++) == '.') || (c == '\\')) {
109 if (dn + n + 2 >= eom)
110 return (-1);
111 *dn++ = '\\';
112 }
113 *dn++ = c;
114 if (cp >= eomorig) /* out of range */
115 return (-1);
116 }
117 break;
118
119 case INDIR_MASK:
120 if (len < 0)
121 len = cp - comp_dn + 1;
122 cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
123 if (cp < msg || cp >= eomorig) /* out of range */
124 return (-1);
125 checked += 2;
126 /*
127 * Check for loops in the compressed name;
128 * if we've looked at the whole message,
129 * there must be a loop.
130 */
131 if (checked >= eomorig - msg)
132 return (-1);
133 break;
134
135 default:
136 return (-1); /* flag error */
137 }
138 }
139 *dn = '\0';
140 if (len < 0)
141 len = cp - comp_dn;
142 return (len);
143}
144
145/*
146 * Compress domain name 'exp_dn' into 'comp_dn'.
147 * Return the size of the compressed name or -1.
148 * 'length' is the size of the array pointed to by 'comp_dn'.
149 * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
150 * is a pointer to the beginning of the message. The list ends with NULL.
151 * 'lastdnptr' is a pointer to the end of the arrary pointed to
152 * by 'dnptrs'. Side effect is to update the list of pointers for
153 * labels inserted into the message as we compress the name.
154 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
155 * is NULL, we don't update the list.
156 */
157int
158dn_comp(const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs,
159 u_char **lastdnptr)
160{
161 u_char *cp, *dn;
162 int c, l;
163 u_char **cpp, **lpp, *sp, *eob;
164 u_char *msg;
165
166 dn = (u_char *)exp_dn;
167 cp = comp_dn;
168 eob = cp + length;
169 lpp = cpp = NULL;
170 if (dnptrs != NULL) {
171 if ((msg = *dnptrs++) != NULL) {
172 for (cpp = dnptrs; *cpp != NULL; cpp++)
173 ;
174 lpp = cpp; /* end of list to search */
175 }
176 } else
177 msg = NULL;
178 for (c = *dn++; c != '\0'; ) {
179 /* look to see if we can use pointers */
180 if (msg != NULL) {
181 if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
182 if (cp+1 >= eob)
183 return (-1);
184 *cp++ = (l >> 8) | INDIR_MASK;
185 *cp++ = l % 256;
186 return (cp - comp_dn);
187 }
188 /* not found, save it */
189 if (lastdnptr != NULL && cpp < lastdnptr-1) {
190 *cpp++ = cp;
191 *cpp = NULL;
192 }
193 }
194 sp = cp++; /* save ptr to length byte */
195 do {
196 if (c == '.') {
197 c = *dn++;
198 break;
199 }
200 if (c == '\\') {
201 if ((c = *dn++) == '\0')
202 break;
203 }
204 if (cp >= eob) {
205 if (msg != NULL)
206 *lpp = NULL;
207 return (-1);
208 }
209 *cp++ = c;
210 } while ((c = *dn++) != '\0');
211 /* catch trailing '.'s but not '..' */
212 if ((l = cp - sp - 1) == 0 && c == '\0') {
213 cp--;
214 break;
215 }
216 if (l <= 0 || l > MAXLABEL) {
217 if (msg != NULL)
218 *lpp = NULL;
219 return (-1);
220 }
221 *sp = l;
222 }
223 if (cp >= eob) {
224 if (msg != NULL)
225 *lpp = NULL;
226 return (-1);
227 }
228 *cp++ = '\0';
229 return (cp - comp_dn);
230}
231
232/*
233 * Skip over a compressed domain name. Return the size or -1.
234 */
235int
236__dn_skipname(const u_char *comp_dn, const u_char *eom)
237{
238 const u_char *cp;
239 int n;
240
241 cp = comp_dn;
242 while (cp < eom && (n = *cp++)) {
243 /*
244 * check for indirection
245 */
246 switch (n & INDIR_MASK) {
247 case 0: /* normal case, n == len */
248 cp += n;
249 continue;
250 case INDIR_MASK: /* indirection */
251 cp++;
252 break;
253 default: /* illegal type */
254 return (-1);
255 }
256 break;
257 }
258 if (cp > eom)
259 return (-1);
260 return (cp - comp_dn);
261}
262
263static int
264mklower(int ch)
265{
266 if (isascii(ch) && isupper(ch))
267 return (tolower(ch));
268 return (ch);
269}
270
271/*
272 * Search for expanded name from a list of previously compressed names.
273 * Return the offset from msg if found or -1.
274 * dnptrs is the pointer to the first name on the list,
275 * not the pointer to the start of the message.
276 */
277static int
278dn_find(u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)
279{
280 u_char *dn, *cp, **cpp;
281 int n;
282 u_char *sp;
283
284 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
285 dn = exp_dn;
286 sp = cp = *cpp;
287 while ((n = *cp++)) {
288 /*
289 * check for indirection
290 */
291 switch (n & INDIR_MASK) {
292 case 0: /* normal case, n == len */
293 while (--n >= 0) {
294 if (*dn == '.')
295 goto next;
296 if (*dn == '\\')
297 dn++;
298 if (mklower(*dn++) != mklower(*cp++))
299 goto next;
300 }
301 if ((n = *dn++) == '\0' && *cp == '\0')
302 return (sp - msg);
303 if (n == '.')
304 continue;
305 goto next;
306
307 case INDIR_MASK: /* indirection */
308 cp = msg + (((n & 0x3f) << 8) | *cp);
309 break;
310
311 default: /* illegal type */
312 return (-1);
313 }
314 }
315 if (*dn == '\0')
316 return (sp - msg);
317 next: ;
318 }
319 return (-1);
320}
321
322/*
323 * Verify that a domain name uses an acceptable character set.
324 */
325
326/*
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.
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}
386
387/*
388 * SOA RNAMEs and RP RNAMEs can have any printable character in their first
389 * label, but the rest of the name has to look like a host name.
390 */
391int
392res_mailok(const char *dn)
393{
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;
439
440 GETSHORT(u, msgp);
441 return (u);
442}
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
456u_int32_t
457_getlong(const u_char *msgp)
458{
459 u_int32_t u;
460
461 GETLONG(u, msgp);
462 return (u);
463}
464
465void
466__putshort(u_int16_t s, u_char *msgp)
467{
468 PUTSHORT(s, msgp);
469}
470
471void
472__putlong(u_int32_t l, u_char *msgp)
473{
474 PUTLONG(l, msgp);
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_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_random.c b/src/lib/libc/net/res_random.c
new file mode 100644
index 0000000000..e22771995a
--- /dev/null
+++ b/src/lib/libc/net/res_random.c
@@ -0,0 +1,275 @@
1/* $OpenBSD: res_random.c,v 1.20 2013/11/12 07:00:24 deraadt Exp $ */
2
3/*
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * Copyright 2008 Damien Miller <djm@openbsd.org>
6 * All rights reserved.
7 *
8 * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
9 * such a mathematical system to generate more random (yet non-repeating)
10 * ids to solve the resolver/named problem. But Niels designed the
11 * actual system based on the constraints.
12 *
13 * Later modified by Damien Miller to wrap the LCG output in a 15-bit
14 * permutation generator based on a Luby-Rackoff block cipher. This
15 * ensures the output is non-repeating and preserves the MSB twiddle
16 * trick, but makes it more resistant to LCG prediction.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 * seed = random 15bit
41 * n = prime, g0 = generator to n,
42 * j = random so that gcd(j,n-1) == 1
43 * g = g0^j mod n will be a generator again.
44 *
45 * X[0] = random seed.
46 * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
47 * with a = 7^(even random) mod m,
48 * b = random with gcd(b,m) == 1
49 * m = 31104 and a maximal period of m-1.
50 *
51 * The transaction id is determined by:
52 * id[n] = seed xor (g^X[n] mod n)
53 *
54 * Effectivly the id is restricted to the lower 15 bits, thus
55 * yielding two different cycles by toggling the msb on and off.
56 * This avoids reuse issues caused by reseeding.
57 *
58 * The output of this generator is then randomly permuted though a
59 * custom 15 bit Luby-Rackoff block cipher.
60 */
61
62#include <sys/types.h>
63#include <netinet/in.h>
64#include <sys/time.h>
65#include <resolv.h>
66
67#include <unistd.h>
68#include <stdlib.h>
69#include <string.h>
70
71#include "thread_private.h"
72
73#define RU_OUT 180 /* Time after wich will be reseeded */
74#define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */
75#define RU_GEN 2 /* Starting generator */
76#define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */
77#define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */
78#define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */
79#define RU_ROUNDS 11 /* Number of rounds for permute (odd) */
80
81struct prf_ctx {
82 /* PRF lookup table for odd rounds (7 bits input to 8 bits output) */
83 u_char prf7[(RU_ROUNDS / 2) * (1 << 7)];
84
85 /* PRF lookup table for even rounds (8 bits input to 7 bits output) */
86 u_char prf8[((RU_ROUNDS + 1) / 2) * (1 << 8)];
87};
88
89#define PFAC_N 3
90const static u_int16_t pfacts[PFAC_N] = {
91 2,
92 3,
93 2729
94};
95
96static u_int16_t ru_x;
97static u_int16_t ru_seed, ru_seed2;
98static u_int16_t ru_a, ru_b;
99static u_int16_t ru_g;
100static u_int16_t ru_counter = 0;
101static u_int16_t ru_msb = 0;
102static struct prf_ctx *ru_prf = NULL;
103static time_t ru_reseed;
104
105static u_int16_t pmod(u_int16_t, u_int16_t, u_int16_t);
106static void res_initid(void);
107
108/*
109 * Do a fast modular exponation, returned value will be in the range
110 * of 0 - (mod-1)
111 */
112static u_int16_t
113pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
114{
115 u_int16_t s, t, u;
116
117 s = 1;
118 t = gen;
119 u = exp;
120
121 while (u) {
122 if (u & 1)
123 s = (s * t) % mod;
124 u >>= 1;
125 t = (t * t) % mod;
126 }
127 return (s);
128}
129
130/*
131 * 15-bit permutation based on Luby-Rackoff block cipher
132 */
133static u_int
134permute15(u_int in)
135{
136 int i;
137 u_int left, right, tmp;
138
139 if (ru_prf == NULL)
140 return in;
141
142 left = (in >> 8) & 0x7f;
143 right = in & 0xff;
144
145 /*
146 * Each round swaps the width of left and right. Even rounds have
147 * a 7-bit left, odd rounds have an 8-bit left. Since this uses an
148 * odd number of rounds, left is always 8 bits wide at the end.
149 */
150 for (i = 0; i < RU_ROUNDS; i++) {
151 if ((i & 1) == 0)
152 tmp = ru_prf->prf8[(i << (8 - 1)) | right] & 0x7f;
153 else
154 tmp = ru_prf->prf7[((i - 1) << (7 - 1)) | right];
155 tmp ^= left;
156 left = right;
157 right = tmp;
158 }
159
160 return (right << 8) | left;
161}
162
163/*
164 * Initializes the seed and chooses a suitable generator. Also toggles
165 * the msb flag. The msb flag is used to generate two distinct
166 * cycles of random numbers and thus avoiding reuse of ids.
167 *
168 * This function is called from res_randomid() when needed, an
169 * application does not have to worry about it.
170 */
171static void
172res_initid(void)
173{
174 u_int16_t j, i;
175 u_int32_t tmp;
176 int noprime = 1;
177 struct timespec ts;
178
179 ru_x = arc4random_uniform(RU_M);
180
181 /* 15 bits of random seed */
182 tmp = arc4random();
183 ru_seed = (tmp >> 16) & 0x7FFF;
184 ru_seed2 = tmp & 0x7FFF;
185
186 /* Determine the LCG we use */
187 tmp = arc4random();
188 ru_b = (tmp & 0xfffe) | 1;
189 ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
190 while (ru_b % 3 == 0)
191 ru_b += 2;
192
193 j = arc4random_uniform(RU_N);
194
195 /*
196 * Do a fast gcd(j,RU_N-1), so we can find a j with
197 * gcd(j, RU_N-1) == 1, giving a new generator for
198 * RU_GEN^j mod RU_N
199 */
200
201 while (noprime) {
202 for (i = 0; i < PFAC_N; i++)
203 if (j % pfacts[i] == 0)
204 break;
205
206 if (i >= PFAC_N)
207 noprime = 0;
208 else
209 j = (j + 1) % RU_N;
210 }
211
212 ru_g = pmod(RU_GEN, j, RU_N);
213 ru_counter = 0;
214
215 /* Initialise PRF for Luby-Rackoff permutation */
216 if (ru_prf == NULL)
217 ru_prf = malloc(sizeof(*ru_prf));
218 if (ru_prf != NULL)
219 arc4random_buf(ru_prf, sizeof(*ru_prf));
220
221 clock_gettime(CLOCK_MONOTONIC, &ts);
222 ru_reseed = ts.tv_sec + RU_OUT;
223 ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
224}
225
226u_int
227res_randomid(void)
228{
229 struct timespec ts;
230 u_int r;
231 _THREAD_PRIVATE_MUTEX(random);
232
233 clock_gettime(CLOCK_MONOTONIC, &ts);
234
235 _THREAD_PRIVATE_MUTEX_LOCK(random);
236
237 if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed)
238 res_initid();
239
240 /* Linear Congruential Generator */
241 ru_x = (ru_a * ru_x + ru_b) % RU_M;
242 ru_counter++;
243
244 r = permute15(ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb;
245
246 _THREAD_PRIVATE_MUTEX_UNLOCK(random);
247
248 return (r);
249}
250
251#if 0
252int
253main(int argc, char **argv)
254{
255 int i, n;
256 u_int16_t wert;
257
258 res_initid();
259
260 printf("Generator: %u\n", ru_g);
261 printf("Seed: %u\n", ru_seed);
262 printf("Reseed at %ld\n", ru_reseed);
263 printf("Ru_X: %u\n", ru_x);
264 printf("Ru_A: %u\n", ru_a);
265 printf("Ru_B: %u\n", ru_b);
266
267 n = argc > 1 ? atoi(argv[1]) : 60001;
268 for (i=0;i<n;i++) {
269 wert = res_randomid();
270 printf("%u\n", wert);
271 }
272 return 0;
273}
274#endif
275
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3
new file mode 100644
index 0000000000..93b365a619
--- /dev/null
+++ b/src/lib/libc/net/resolver.3
@@ -0,0 +1,398 @@
1.\" $OpenBSD: resolver.3,v 1.29 2014/01/21 03:15:45 schwarze Exp $
2.\"
3.\" Copyright (c) 1985, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. 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: January 21 2014 $
31.Dt RESOLVER 3
32.Os
33.Sh NAME
34.Nm res_query ,
35.Nm res_search ,
36.Nm res_mkquery ,
37.Nm res_send ,
38.Nm res_init ,
39.Nm dn_comp ,
40.Nm dn_expand
41.Nd resolver routines
42.Sh SYNOPSIS
43.In sys/types.h
44.In netinet/in.h
45.In arpa/nameser.h
46.In resolv.h
47.Ft int
48.Fo res_query
49.Fa "const char *dname"
50.Fa "int class"
51.Fa "int type"
52.Fa "unsigned char *answer"
53.Fa "int anslen"
54.Fc
55.Ft int
56.Fo res_search
57.Fa "const char *dname"
58.Fa "int class"
59.Fa "int type"
60.Fa "unsigned char *answer"
61.Fa "int anslen"
62.Fc
63.Ft int
64.Fo res_mkquery
65.Fa "int op"
66.Fa "const char *dname"
67.Fa "int class"
68.Fa "int type"
69.Fa "const unsigned char *data"
70.Fa "int datalen"
71.Fa "const unsigned char *newrr"
72.Fa "unsigned char *buf"
73.Fa "int buflen"
74.Fc
75.Ft int
76.Fo res_send
77.Fa "const unsigned char *msg"
78.Fa "int msglen"
79.Fa "unsigned char *answer"
80.Fa "int anslen"
81.Fc
82.Ft int
83.Fn res_init "void"
84.Ft int
85.Fo dn_comp
86.Fa "const char *exp_dn"
87.Fa "unsigned char *comp_dn"
88.Fa "int length"
89.Fa "unsigned char **dnptrs"
90.Fa "unsigned char **lastdnptr"
91.Fc
92.Ft int
93.Fo dn_expand
94.Fa "const unsigned char *msg"
95.Fa "const unsigned char *eomorig"
96.Fa "const unsigned char *comp_dn"
97.Fa "char *exp_dn"
98.Fa "int length"
99.Fc
100.Sh DESCRIPTION
101These routines are used for making, sending, and interpreting
102query and reply messages with Internet domain name servers.
103.Pp
104Global configuration and state information that is used by the
105resolver routines is kept in the structure
106.Li _res .
107Most of the values have reasonable defaults and can be ignored.
108Options stored in
109.Li _res.options
110are defined in
111.In resolv.h
112and are as follows.
113Options are stored as a simple bit mask containing the bitwise OR
114of the options enabled.
115.Bl -tag -width RES_USE_DNSSEC
116.It Dv RES_INIT
117True if the initial name server address and default domain name are
118initialized (i.e.\&
119.Fn res_init
120has been called).
121.It Dv RES_DEBUG
122Print debugging messages,
123if libc is compiled with
124.Dv DEBUG .
125By default on
126.Ox
127this option does nothing.
128.It Dv RES_AAONLY
129Accept authoritative answers only.
130With this option,
131.Fn res_send
132should continue until it finds an authoritative answer or finds an error.
133Currently this is not implemented.
134.It Dv RES_USEVC
135Use TCP connections for queries instead of UDP datagrams.
136.It Dv RES_PRIMARY
137Query the primary name server only.
138Currently this is not implemented.
139.It Dv RES_IGNTC
140Ignore truncation errors, i.e. don't retry with TCP.
141.It Dv RES_RECURSE
142Set the recursion-desired bit in queries.
143.Pf ( Fn res_send
144does not do iterative queries and expects the name server
145to handle recursion.)
146This option is enabled by default.
147.It Dv RES_DEFNAMES
148If set,
149.Fn res_search
150will append the default domain name to single-component names
151(those that do not contain a dot).
152This option is enabled by default.
153.It Dv RES_STAYOPEN
154Used with
155.Dv RES_USEVC
156to keep the TCP connection open between queries.
157This is useful only in programs that regularly do many queries.
158UDP should be the normal mode used.
159.It Dv RES_DNSRCH
160If this option is set,
161.Fn res_search
162will search for host names in the current domain and in parent domains; see
163.Xr hostname 7 .
164This is used by the standard host lookup routine
165.Xr gethostbyname 3 .
166This option is enabled by default.
167.It Dv RES_INSECURE_1
168Do not require the IP source address on the reply packet
169to be equal to the server's address.
170.It Dv RES_INSECURE_2
171Do not check if the query section of the reply packet
172is equal to that of the query packet.
173.It Dv RES_NOALIASES
174Turn off the
175.Ev HOSTALIASES
176feature.
177See
178.Xr hostname 7
179for more information.
180.It Dv RES_USE_INET6
181Enables support for IPv6-only applications.
182This causes IPv4 addresses to be returned as an IPv4 mapped address.
183For example, 10.1.1.1 will be returned as ::ffff:10.1.1.1.
184The option is not meaningful on
185.Ox .
186.It Dv RES_USE_EDNS0
187Attach an OPT pseudo-RR for the EDNS0 extension,
188as specified in RFC 2671.
189This informs DNS servers of a client's receive buffer size,
190allowing them to take advantage of a non-default receive buffer size,
191and thus to send larger replies.
192DNS query packets with the EDNS0 extension are not compatible with
193non-EDNS0 DNS servers.
194.It Dv RES_USE_DNSSEC
195Request that the resolver uses
196Domain Name System Security Extensions (DNSSEC),
197as defined in RFCs 4033, 4034, and 4035.
198.El
199.Pp
200The
201.Fn res_init
202routine reads the configuration file (if any; see
203.Xr resolv.conf 5 )
204to get the default domain name, search list, and the Internet address
205of the local name server(s).
206If no server is configured, the host running
207the resolver is tried.
208The current domain name is defined by the hostname
209if not specified in the configuration file;
210it can be overridden by the environment variable
211.Ev LOCALDOMAIN .
212This environment variable may contain several blank-separated
213tokens if you wish to override the
214.Fa search list
215on a per-process basis.
216This is similar to the
217.Fa search
218command in the configuration file.
219Another environment variable
220.Ev RES_OPTIONS
221can be set to override certain internal resolver options which
222are otherwise set by changing fields in the
223.Fa _res
224structure or are inherited from the configuration file's
225.Fa options
226command.
227The syntax of the
228.Ev RES_OPTIONS
229environment variable is explained in
230.Xr resolv.conf 5 .
231Initialization normally occurs on the first call
232to one of the following routines.
233.Pp
234The
235.Fn res_query
236function provides an interface to the server query mechanism.
237It constructs a query, sends it to the local server,
238awaits a response, and makes preliminary checks on the reply.
239The query requests information of the specified
240.Fa type
241and
242.Fa class
243for the specified fully qualified domain name
244.Fa dname .
245The reply message is left in the
246.Fa answer
247buffer with length
248.Fa anslen
249supplied by the caller.
250Values for the
251.Fa class
252and
253.Fa type
254fields
255are defined in
256.In arpa/nameser.h .
257.Pp
258The
259.Fn res_search
260routine makes a query and awaits a response like
261.Fn res_query ,
262but in addition, it implements the default and search rules controlled by the
263.Dv RES_DEFNAMES
264and
265.Dv RES_DNSRCH
266options.
267It returns the first successful reply.
268.Pp
269The remaining routines are lower-level routines used by
270.Fn res_query .
271The
272.Fn res_mkquery
273function constructs a standard query message and places it in
274.Fa buf .
275It returns the size of the query, or \-1 if the query is larger than
276.Fa buflen .
277The query type
278.Fa op
279is usually
280.Dv QUERY ,
281but can be any of the query types defined in
282.In arpa/nameser.h .
283The domain name for the query is given by
284.Fa dname .
285.Fa newrr
286is currently unused but is intended for making update messages.
287.Pp
288The
289.Fn res_send
290routine sends a pre-formatted query and returns an answer.
291It will call
292.Fn res_init
293if
294.Dv RES_INIT
295is not set, send the query to the local name server, and
296handle timeouts and retries.
297The length of the reply message is returned, or \-1 if there were errors.
298.Pp
299The
300.Fn dn_comp
301function compresses the domain name
302.Fa exp_dn
303and stores it in
304.Fa comp_dn .
305The size of the compressed name is returned or \-1 if there were errors.
306The size of the array pointed to by
307.Fa comp_dn
308is given by
309.Fa length .
310The compression uses an array of pointers
311.Fa dnptrs
312to previously compressed names in the current message.
313The first pointer points
314to the beginning of the message and the list ends with
315.Dv NULL .
316The limit to the array is specified by
317.Fa lastdnptr .
318A side effect of
319.Fn dn_comp
320is to update the list of pointers for labels inserted into the message
321as the name is compressed.
322If
323.Fa dnptrs
324is
325.Dv NULL ,
326names are not compressed.
327If
328.Fa lastdnptr
329is
330.Dv NULL ,
331the list of labels is not updated.
332.Pp
333The
334.Fn dn_expand
335entry expands the compressed domain name
336.Fa comp_dn
337to a full domain name.
338The compressed name is contained in a query or reply message;
339.Fa msg
340is a pointer to the beginning of the message.
341The uncompressed name is placed in the buffer indicated by
342.Fa exp_dn
343which is of size
344.Fa length .
345The size of compressed name is returned or \-1 if there was an error.
346.Sh FILES
347.Bl -tag -width "/etc/resolv.confXX"
348.It Pa /etc/resolv.conf
349The configuration file.
350.El
351.Sh SEE ALSO
352.Xr gethostbyname 3 ,
353.Xr resolv.conf 5 ,
354.Xr hostname 7 ,
355.Xr named 8
356.Rs
357.%T Name Server Operations Guide for BIND
358.Re
359.Sh STANDARDS
360.Rs
361.%A M. Stahl
362.%D November 1987
363.%R RFC 1032
364.%T Domain Administrators Guide
365.Re
366.Pp
367.Rs
368.%A M. Lottor
369.%D November 1987
370.%R RFC 1033
371.%T Domain Administrators Operations Guide
372.Re
373.Pp
374.Rs
375.%A P. Mockapetris
376.%D November 1987
377.%R RFC 1034
378.%T Domain Names \(en Concepts and Facilities
379.Re
380.Pp
381.Rs
382.%A P. Mockapetris
383.%D November 1987
384.%R RFC 1035
385.%T Domain Names \(en Implementation and Specification
386.Re
387.Pp
388.Rs
389.%A J. Klensin
390.%D October 2008
391.%R RFC 5321
392.%T Simple Mail Transfer Protocol
393.Re
394.Sh HISTORY
395The
396.Nm
397function appeared in
398.Bx 4.3 .
diff --git a/src/lib/libc/net/rresvport.c b/src/lib/libc/net/rresvport.c
new file mode 100644
index 0000000000..ccc411500b
--- /dev/null
+++ b/src/lib/libc/net/rresvport.c
@@ -0,0 +1,107 @@
1/* $OpenBSD: rresvport.c,v 1.9 2005/11/10 10:00:17 espie Exp $ */
2/*
3 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
4 * Copyright (c) 1983, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/param.h>
33#include <sys/socket.h>
34#include <sys/stat.h>
35
36#include <netinet/in.h>
37#include <arpa/inet.h>
38
39#include <signal.h>
40#include <fcntl.h>
41#include <netdb.h>
42#include <unistd.h>
43#include <pwd.h>
44#include <errno.h>
45#include <stdio.h>
46#include <ctype.h>
47#include <string.h>
48#include <syslog.h>
49#include <stdlib.h>
50#include <netgroup.h>
51
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/ruserok.c b/src/lib/libc/net/ruserok.c
new file mode 100644
index 0000000000..21646c156b
--- /dev/null
+++ b/src/lib/libc/net/ruserok.c
@@ -0,0 +1,438 @@
1/*
2 * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved.
3 * Copyright (c) 1983, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/socket.h>
32#include <sys/stat.h>
33
34#include <netinet/in.h>
35#include <arpa/inet.h>
36
37#include <ctype.h>
38#include <errno.h>
39#include <fcntl.h>
40#include <limits.h>
41#include <netdb.h>
42#include <netgroup.h>
43#include <pwd.h>
44#include <signal.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <syslog.h>
49#include <unistd.h>
50
51int __ivaliduser(FILE *, in_addr_t, const char *, 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 __check_rhosts_file = 1;
58char *__rcmd_errstr;
59
60int
61ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
62{
63 struct addrinfo hints, *res, *r;
64 int error;
65
66 memset(&hints, 0, sizeof(hints));
67 hints.ai_family = PF_UNSPEC;
68 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
69 error = getaddrinfo(rhost, "0", &hints, &res);
70 if (error)
71 return (-1);
72
73 for (r = res; r; r = r->ai_next) {
74 if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser,
75 luser) == 0) {
76 freeaddrinfo(res);
77 return (0);
78 }
79 }
80 freeaddrinfo(res);
81 return (-1);
82}
83
84/*
85 * New .rhosts strategy: We are passed an ip address. We spin through
86 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
87 * has ip addresses, we don't have to trust a nameserver. When it
88 * contains hostnames, we spin through the list of addresses the nameserver
89 * gives us and look for a match.
90 *
91 * Returns 0 if ok, -1 if not ok.
92 */
93int
94iruserok(u_int32_t raddr, int superuser, const char *ruser, const char *luser)
95{
96 struct sockaddr_in sin;
97
98 memset(&sin, 0, sizeof(sin));
99 sin.sin_family = AF_INET;
100 sin.sin_len = sizeof(struct sockaddr_in);
101 memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr));
102 return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser,
103 luser);
104}
105
106int
107iruserok_sa(const void *raddr, int rlen, int superuser, const char *ruser,
108 const char *luser)
109{
110 struct sockaddr *sa;
111 char *cp;
112 struct stat sbuf;
113 struct passwd *pwd;
114 FILE *hostf;
115 uid_t uid;
116 int first;
117 char pbuf[PATH_MAX];
118
119 sa = (struct sockaddr *)raddr;
120 first = 1;
121 hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
122again:
123 if (hostf) {
124 if (__ivaliduser_sa(hostf, sa, rlen, luser, ruser) == 0) {
125 (void)fclose(hostf);
126 return (0);
127 }
128 (void)fclose(hostf);
129 }
130 if (first == 1 && (__check_rhosts_file || superuser)) {
131 int len;
132
133 first = 0;
134 if ((pwd = getpwnam(luser)) == NULL)
135 return (-1);
136 len = snprintf(pbuf, sizeof pbuf, "%s/.rhosts", pwd->pw_dir);
137 if (len < 0 || len >= sizeof pbuf)
138 return (-1);
139
140 /*
141 * Change effective uid while opening .rhosts. If root and
142 * reading an NFS mounted file system, can't read files that
143 * are protected read/write owner only.
144 */
145 uid = geteuid();
146 (void)seteuid(pwd->pw_uid);
147 hostf = fopen(pbuf, "r");
148 (void)seteuid(uid);
149
150 if (hostf == NULL)
151 return (-1);
152 /*
153 * If not a regular file, or is owned by someone other than
154 * user or root or if writeable by anyone but the owner, quit.
155 */
156 cp = NULL;
157 if (lstat(pbuf, &sbuf) < 0)
158 cp = ".rhosts lstat failed";
159 else if (!S_ISREG(sbuf.st_mode))
160 cp = ".rhosts not regular file";
161 else if (fstat(fileno(hostf), &sbuf) < 0)
162 cp = ".rhosts fstat failed";
163 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
164 cp = "bad .rhosts owner";
165 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
166 cp = ".rhosts writable by other than owner";
167 /* If there were any problems, quit. */
168 if (cp) {
169 __rcmd_errstr = cp;
170 (void)fclose(hostf);
171 return (-1);
172 }
173 goto again;
174 }
175 return (-1);
176}
177
178/*
179 * XXX
180 * Don't make static, used by lpd(8).
181 *
182 * Returns 0 if ok, -1 if not ok.
183 */
184int
185__ivaliduser(FILE *hostf, in_addr_t raddrl, const char *luser,
186 const char *ruser)
187{
188 struct sockaddr_in sin;
189
190 memset(&sin, 0, sizeof(sin));
191 sin.sin_family = AF_INET;
192 sin.sin_len = sizeof(struct sockaddr_in);
193 memcpy(&sin.sin_addr, &raddrl, sizeof(sin.sin_addr));
194 return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len,
195 luser, ruser);
196}
197
198int
199__ivaliduser_sa(FILE *hostf, struct sockaddr *raddr, socklen_t salen,
200 const char *luser, const char *ruser)
201{
202 char *user, *p;
203 char *buf;
204 const char *auser, *ahost;
205 int hostok, userok;
206 char *rhost = (char *)-1;
207 char domain[MAXHOSTNAMELEN];
208 size_t buflen;
209
210 getdomainname(domain, sizeof(domain));
211
212 while ((buf = fgetln(hostf, &buflen))) {
213 p = buf;
214 if (*p == '#')
215 continue;
216 while (p < buf + buflen && *p != '\n' && *p != ' ' && *p != '\t') {
217 if (!isprint((unsigned char)*p))
218 goto bail;
219 *p = isupper((unsigned char)*p) ?
220 tolower((unsigned char)*p) : *p;
221 p++;
222 }
223 if (p >= buf + buflen)
224 continue;
225 if (*p == ' ' || *p == '\t') {
226 *p++ = '\0';
227 while (p < buf + buflen && (*p == ' ' || *p == '\t'))
228 p++;
229 if (p >= buf + buflen)
230 continue;
231 user = p;
232 while (p < buf + buflen && *p != '\n' && *p != ' ' &&
233 *p != '\t') {
234 if (!isprint((unsigned char)*p))
235 goto bail;
236 p++;
237 }
238 } else
239 user = p;
240 *p = '\0';
241
242 if (p == buf)
243 continue;
244
245 auser = *user ? user : luser;
246 ahost = buf;
247
248 if (strlen(ahost) >= MAXHOSTNAMELEN)
249 continue;
250
251 /*
252 * innetgr() must lookup a hostname (we do not attempt
253 * to change the semantics so that netgroups may have
254 * #.#.#.# addresses in the list.)
255 */
256 if (ahost[0] == '+')
257 switch (ahost[1]) {
258 case '\0':
259 hostok = 1;
260 break;
261 case '@':
262 if (rhost == (char *)-1)
263 rhost = __gethostloop(raddr, salen);
264 hostok = 0;
265 if (rhost)
266 hostok = innetgr(&ahost[2], rhost,
267 NULL, domain);
268 break;
269 default:
270 hostok = __icheckhost(raddr, salen, &ahost[1]);
271 break;
272 }
273 else if (ahost[0] == '-')
274 switch (ahost[1]) {
275 case '\0':
276 hostok = -1;
277 break;
278 case '@':
279 if (rhost == (char *)-1)
280 rhost = __gethostloop(raddr, salen);
281 hostok = 0;
282 if (rhost)
283 hostok = -innetgr(&ahost[2], rhost,
284 NULL, domain);
285 break;
286 default:
287 hostok = -__icheckhost(raddr, salen, &ahost[1]);
288 break;
289 }
290 else
291 hostok = __icheckhost(raddr, salen, ahost);
292
293
294 if (auser[0] == '+')
295 switch (auser[1]) {
296 case '\0':
297 userok = 1;
298 break;
299 case '@':
300 userok = innetgr(&auser[2], NULL, ruser,
301 domain);
302 break;
303 default:
304 userok = strcmp(ruser, &auser[1]) ? 0 : 1;
305 break;
306 }
307 else if (auser[0] == '-')
308 switch (auser[1]) {
309 case '\0':
310 userok = -1;
311 break;
312 case '@':
313 userok = -innetgr(&auser[2], NULL, ruser,
314 domain);
315 break;
316 default:
317 userok = strcmp(ruser, &auser[1]) ? 0 : -1;
318 break;
319 }
320 else
321 userok = strcmp(ruser, auser) ? 0 : 1;
322
323 /* Check if one component did not match */
324 if (hostok == 0 || userok == 0)
325 continue;
326
327 /* Check if we got a forbidden pair */
328 if (userok <= -1 || hostok <= -1)
329 return (-1);
330
331 /* Check if we got a valid pair */
332 if (hostok >= 1 && userok >= 1)
333 return (0);
334 }
335bail:
336 return (-1);
337}
338
339/*
340 * Returns "true" if match, 0 if no match. If we do not find any
341 * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work.
342 */
343static int
344__icheckhost(struct sockaddr *raddr, socklen_t salen, const char *lhost)
345{
346 struct addrinfo hints, *res, *r;
347 char h1[NI_MAXHOST], h2[NI_MAXHOST];
348 int error;
349 const int niflags = NI_NUMERICHOST;
350
351 h1[0] = '\0';
352 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
353 niflags) != 0)
354 return (0);
355
356 /* Resolve laddr into sockaddr */
357 memset(&hints, 0, sizeof(hints));
358 hints.ai_family = raddr->sa_family;
359 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
360 res = NULL;
361 error = getaddrinfo(lhost, "0", &hints, &res);
362 if (error)
363 return (0);
364
365 /*
366 * Try string comparisons between raddr and laddr.
367 */
368 for (r = res; r; r = r->ai_next) {
369 h2[0] = '\0';
370 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
371 NULL, 0, niflags) != 0)
372 continue;
373 if (strcmp(h1, h2) == 0) {
374 freeaddrinfo(res);
375 return (1);
376 }
377 }
378
379 /* No match. */
380 freeaddrinfo(res);
381 return (0);
382}
383
384/*
385 * Return the hostname associated with the supplied address.
386 * Do a reverse lookup as well for security. If a loop cannot
387 * be found, pack the result of inet_ntoa() into the string.
388 */
389static char *
390__gethostloop(struct sockaddr *raddr, socklen_t salen)
391{
392 static char remotehost[NI_MAXHOST];
393 char h1[NI_MAXHOST], h2[NI_MAXHOST];
394 struct addrinfo hints, *res, *r;
395 int error;
396 const int niflags = NI_NUMERICHOST;
397
398 h1[0] = remotehost[0] = '\0';
399 if (getnameinfo(raddr, salen, remotehost, sizeof(remotehost),
400 NULL, 0, NI_NAMEREQD) != 0)
401 return (NULL);
402 if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0,
403 niflags) != 0)
404 return (NULL);
405
406 /*
407 * Look up the name and check that the supplied
408 * address is in the list
409 */
410 memset(&hints, 0, sizeof(hints));
411 hints.ai_family = raddr->sa_family;
412 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
413 hints.ai_flags = AI_CANONNAME;
414 res = NULL;
415 error = getaddrinfo(remotehost, "0", &hints, &res);
416 if (error)
417 return (NULL);
418
419 for (r = res; r; r = r->ai_next) {
420 h2[0] = '\0';
421 if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2),
422 NULL, 0, niflags) != 0)
423 continue;
424 if (strcmp(h1, h2) == 0) {
425 freeaddrinfo(res);
426 return (remotehost);
427 }
428 }
429
430 /*
431 * either the DNS adminstrator has made a configuration
432 * mistake, or someone has attempted to spoof us
433 */
434 syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s",
435 h1, res->ai_canonname ? res->ai_canonname : remotehost);
436 freeaddrinfo(res);
437 return (NULL);
438}
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c
new file mode 100644
index 0000000000..1bfc80b87a
--- /dev/null
+++ b/src/lib/libc/net/send.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: send.c,v 1.5 2005/08/06 20:30:04 espie Exp $ */
2/*
3 * Copyright (c) 1988, 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
31#include <sys/types.h>
32#include <sys/socket.h>
33
34#include <stddef.h>
35
36ssize_t
37send(int s, const void *msg, size_t len, int flags)
38{
39 return (sendto(s, msg, len, flags, NULL, 0));
40}
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c
new file mode 100644
index 0000000000..a22d49d047
--- /dev/null
+++ b/src/lib/libc/net/vars6.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: vars6.c,v 1.2 2003/05/10 10:56:47 jmc Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <netinet/in.h>
34
35/*
36 * Definitions of some constant IPv6 addresses.
37 */
38const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
39const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
40const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
41const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
42
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000000..953c53382f
--- /dev/null
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,63 @@
1# $OpenBSD: Makefile.inc,v 1.49 2014/03/18 22:36:29 miod Exp $
2
3# stdlib sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib
5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
7 cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \
9 lldiv.c lsearch.c malloc.c merge.c posix_pty.c qsort.c radixsort.c \
10 rand.c random.c realpath.c setenv.c strtoimax.c strtol.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
14
15.if (${MACHINE_CPU} == "i386")
16SRCS+= abs.S div.S labs.S ldiv.S
17.elif (${MACHINE_CPU} == "vax")
18SRCS+= abs.c div.c labs.c ldiv.c
19.elif (${MACHINE_CPU} == "alpha")
20# XXX should be .S's
21SRCS+= abs.c div.c labs.c ldiv.c
22.else
23SRCS+= abs.c div.c labs.c ldiv.c
24.endif
25
26.if (${MACHINE_CPU} == "vax")
27SRCS+= insque.S remque.S
28.else
29SRCS+= insque.c remque.c
30.endif
31
32MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
33 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \
34 getsubopt.3 hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 \
35 lldiv.3 lsearch.3 malloc.3 posix_memalign.3 posix_openpt.3 ptsname.3 \
36 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \
37 strtod.3 strtonum.3 strtol.3 strtoul.3 system.3 tsearch.3
38
39MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
41MLINKS+=getopt_long.3 getopt_long_only.3
42MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3
43MLINKS+=insque.3 remque.3
44MLINKS+=labs.3 llabs.3
45MLINKS+=lsearch.3 lfind.3
46MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
47MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
48MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3
49MLINKS+=radixsort.3 sradixsort.3
50MLINKS+=rand.3 srand.3 rand.3 rand_r.3
51MLINKS+=random.3 initstate.3 random.3 setstate.3
52MLINKS+=random.3 srandom.3 random.3 srandomdev.3
53MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3
54MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3
55MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3
56MLINKS+=ptsname.3 grantpt.3 ptsname.3 unlockpt.3
57MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3
58MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3
59MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 strtoul.3 strtoumax.3
60MLINKS+=tsearch.3 tfind.3
61MLINKS+=tsearch.3 tdelete.3
62MLINKS+=tsearch.3 twalk.3
63MLINKS+=a64l.3 l64a.3
diff --git a/src/lib/libc/stdlib/_Exit.c b/src/lib/libc/stdlib/_Exit.c
new file mode 100644
index 0000000000..ccf64c2e87
--- /dev/null
+++ b/src/lib/libc/stdlib/_Exit.c
@@ -0,0 +1,22 @@
1/* $OpenBSD: _Exit.c,v 1.3 2013/04/03 03:39:29 guenther Exp $ */
2
3/*
4 * Placed in the public domain by Todd C. Miller on January 21, 2004.
5 */
6
7#include <stdlib.h>
8#include <unistd.h>
9
10/*
11 * _Exit() is the ISO/ANSI C99 equivalent of the POSIX _exit() function.
12 * No atexit() handlers are called and no signal handlers are run.
13 * Whether or not stdio buffers are flushed or temporary files are removed
14 * is implementation-dependent in C99. Indeed, POSIX specifies that
15 * _Exit() must *not* flush stdio buffers or remove temporary files, but
16 * rather must behave exactly like _exit()
17 */
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
new file mode 100644
index 0000000000..7c950f7cee
--- /dev/null
+++ b/src/lib/libc/stdlib/_rand48.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: _rand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17unsigned short __rand48_seed[3] = {
18 RAND48_SEED_0,
19 RAND48_SEED_1,
20 RAND48_SEED_2
21};
22unsigned short __rand48_mult[3] = {
23 RAND48_MULT_0,
24 RAND48_MULT_1,
25 RAND48_MULT_2
26};
27unsigned short __rand48_add = RAND48_ADD;
28
29void
30__dorand48(unsigned short xseed[3])
31{
32 unsigned long accu;
33 unsigned short temp[2];
34
35 accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
36 (unsigned long) __rand48_add;
37 temp[0] = (unsigned short) accu; /* lower 16 bits */
38 accu >>= sizeof(unsigned short) * 8;
39 accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
40 (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
41 temp[1] = (unsigned short) accu; /* middle 16 bits */
42 accu >>= sizeof(unsigned short) * 8;
43 accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
44 xseed[0] = temp[0];
45 xseed[1] = temp[1];
46 xseed[2] = (unsigned short) accu;
47}
diff --git a/src/lib/libc/stdlib/a64l.3 b/src/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000000..11a74604ac
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.3
@@ -0,0 +1,133 @@
1.\" $OpenBSD: a64l.3,v 1.12 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: June 5 2013 $
18.Dt A64L 3
19.Os
20.Sh NAME
21.Nm a64l ,
22.Nm l64a
23.Nd convert between 32-bit integer and radix-64 ASCII string
24.Sh SYNOPSIS
25.In stdlib.h
26.Ft long
27.Fn a64l "const char *s"
28.Ft char *
29.Fn l64a "long l"
30.Sh DESCRIPTION
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 STANDARDS
112The
113.Fn a64l
114and
115.Fn l64a
116functions conform to
117.St -xpg4.2 .
118.Sh CAVEATS
119The value returned by
120.Fn l64a
121is a pointer into a static buffer, the contents of which
122will be overwritten by subsequent calls.
123.Pp
124The value returned by
125.Fn a64l
126may be incorrect if the value is too large; for that reason, only strings
127that resulted from a call to
128.Fn l64a
129should be used to call
130.Fn a64l .
131.Pp
132If a long integer is larger than 32 bits, only the low-order
13332 bits are used.
diff --git a/src/lib/libc/stdlib/a64l.c b/src/lib/libc/stdlib/a64l.c
new file mode 100644
index 0000000000..5312929c6f
--- /dev/null
+++ b/src/lib/libc/stdlib/a64l.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: a64l.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <errno.h>
8#include <stdlib.h>
9
10long
11a64l(const char *s)
12{
13 long value, digit, shift;
14 int i;
15
16 if (s == NULL) {
17 errno = EINVAL;
18 return(-1L);
19 }
20
21 value = 0;
22 shift = 0;
23 for (i = 0; *s && i < 6; i++, s++) {
24 if (*s >= '.' && *s <= '/')
25 digit = *s - '.';
26 else if (*s >= '0' && *s <= '9')
27 digit = *s - '0' + 2;
28 else if (*s >= 'A' && *s <= 'Z')
29 digit = *s - 'A' + 12;
30 else if (*s >= 'a' && *s <= 'z')
31 digit = *s - 'a' + 38;
32 else {
33 errno = EINVAL;
34 return(-1L);
35 }
36
37 value |= digit << shift;
38 shift += 6;
39 }
40
41 return(value);
42}
diff --git a/src/lib/libc/stdlib/abort.3 b/src/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000000..322d629930
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.3
@@ -0,0 +1,68 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" 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. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: abort.3,v 1.10 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt ABORT 3
36.Os
37.Sh NAME
38.Nm abort
39.Nd cause abnormal program termination
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft void
43.Fn abort void
44.Sh DESCRIPTION
45The
46.Fn abort
47function causes abnormal program termination to occur, unless the signal
48.Dv SIGABRT
49is being caught and the signal handler does not return.
50.Pp
51Any open streams are flushed and closed.
52.Sh RETURN VALUES
53The
54.Fn abort
55function never returns.
56.Sh SEE ALSO
57.Xr sigaction 2 ,
58.Xr exit 3
59.Sh STANDARDS
60The
61.Fn abort
62function conforms to
63.St -p1003.1-90 .
64.Sh HISTORY
65The
66.Fn abort
67function first appeared in
68.At v5 .
diff --git a/src/lib/libc/stdlib/abort.c b/src/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000000..4c8dc70a1d
--- /dev/null
+++ b/src/lib/libc/stdlib/abort.c
@@ -0,0 +1,80 @@
1/* $OpenBSD: abort.c,v 1.16 2012/11/10 03:46:11 guenther Exp $ */
2/*
3 * Copyright (c) 1985 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <signal.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include "thread_private.h"
35#include "atexit.h"
36
37int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
38
39void
40abort(void)
41{
42 struct atexit *p = __atexit;
43 static int cleanup_called = 0;
44 sigset_t mask;
45
46
47 sigfillset(&mask);
48 /*
49 * don't block SIGABRT to give any handler a chance; we ignore
50 * any errors -- X311J doesn't allow abort to return anyway.
51 */
52 sigdelset(&mask, SIGABRT);
53 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
54
55 /*
56 * POSIX requires we flush stdio buffers on abort
57 */
58 if (cleanup_called == 0) {
59 /* the cleanup routine lives in fns[0] on the last page */
60 while (p != NULL && p->next != NULL)
61 p = p->next;
62 /* the check for fn_dso == NULL is mostly paranoia */
63 if (p != NULL && p->fns[0].fn_dso == NULL &&
64 p->fns[0].fn_ptr.std_func != NULL) {
65 cleanup_called = 1;
66 (*p->fns[0].fn_ptr.std_func)();
67 }
68 }
69
70 (void)raise(SIGABRT);
71
72 /*
73 * if SIGABRT ignored, or caught and the handler returns, do
74 * it again, only harder.
75 */
76 (void)signal(SIGABRT, SIG_DFL);
77 (void)_thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
78 (void)raise(SIGABRT);
79 _exit(1);
80}
diff --git a/src/lib/libc/stdlib/abs.3 b/src/lib/libc/stdlib/abs.3
new file mode 100644
index 0000000000..420bdf6fdf
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: abs.3,v 1.11 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt ABS 3
36.Os
37.Sh NAME
38.Nm abs
39.Nd integer absolute value function
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft int
43.Fn abs "int j"
44.Sh DESCRIPTION
45The
46.Fn abs
47function computes the absolute value of the integer
48.Fa j .
49.Sh RETURN VALUES
50The
51.Fn abs
52function returns the absolute value.
53.Sh SEE ALSO
54.Xr cabs 3 ,
55.Xr floor 3 ,
56.Xr hypot 3 ,
57.Xr imaxabs 3 ,
58.Xr labs 3
59.Sh STANDARDS
60The
61.Fn abs
62function conforms to
63.St -ansiC .
64.Sh HISTORY
65The
66.Fn abs
67function first appeared in
68.At v6 .
69.Sh BUGS
70The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/abs.c b/src/lib/libc/stdlib/abs.c
new file mode 100644
index 0000000000..5d2fbae69f
--- /dev/null
+++ b/src/lib/libc/stdlib/abs.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: abs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33int
34abs(int j)
35{
36 return(j < 0 ? -j : j);
37}
diff --git a/src/lib/libc/stdlib/alloca.3 b/src/lib/libc/stdlib/alloca.3
new file mode 100644
index 0000000000..47e9b97143
--- /dev/null
+++ b/src/lib/libc/stdlib/alloca.3
@@ -0,0 +1,76 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $OpenBSD: alloca.3,v 1.13 2013/06/05 03:39:23 tedu Exp $
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt ALLOCA 3
32.Os
33.Sh NAME
34.Nm alloca
35.Nd memory allocator
36.Sh SYNOPSIS
37.In stdlib.h
38.Ft void *
39.Fn alloca "size_t size"
40.Sh DESCRIPTION
41The
42.Fn alloca
43function allocates
44.Fa size
45bytes of space in the stack frame of the caller.
46This temporary space is automatically freed on return.
47.Sh RETURN VALUES
48The
49.Fn alloca
50function returns a pointer to the beginning of the allocated space.
51.Sh SEE ALSO
52.Xr pagesize 1 ,
53.Xr brk 2 ,
54.Xr calloc 3 ,
55.Xr malloc 3 ,
56.Xr realloc 3
57.\" .Sh HISTORY
58.\" The
59.\" .Fn alloca
60.\" function appeared in
61.\" .Bx ?? .
62.\" The function appeared in 32v, pwb and pwb.2 and in 3bsd 4bsd
63.\" The first man page (or link to a man page that I can find at the
64.\" moment is 4.3...
65.Sh BUGS
66The
67.Fn alloca
68function is slightly unsafe because it cannot ensure that the pointer
69returned points to a valid and usable block of memory.
70The allocation made may exceed the bounds of the stack, or even go
71further into other objects in memory, and
72.Fn alloca
73cannot determine such an error.
74Avoid
75.Fn alloca
76with large unbounded allocations.
diff --git a/src/lib/libc/stdlib/atexit.3 b/src/lib/libc/stdlib/atexit.3
new file mode 100644
index 0000000000..8e3ac3e60f
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.3
@@ -0,0 +1,77 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: atexit.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt ATEXIT 3
36.Os
37.Sh NAME
38.Nm atexit
39.Nd register a function to be called on exit
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft int
43.Fn atexit "void (*function)(void)"
44.Sh DESCRIPTION
45The
46.Fn atexit
47function registers the given
48.Fa function
49to be called at program exit, whether via
50.Xr exit 3
51or via return from the program's
52.Fn main .
53Functions so registered are called in reverse order;
54no arguments are passed.
55At least 32 functions can always be registered,
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
64.Rv -std atexit
65.Sh ERRORS
66.Bl -tag -width Er
67.It Bq Er ENOMEM
68No memory was available to add the function to the list.
69The existing list of functions is unmodified.
70.El
71.Sh SEE ALSO
72.Xr exit 3
73.Sh STANDARDS
74The
75.Fn atexit
76function conforms to
77.St -ansiC .
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
new file mode 100644
index 0000000000..049da3261d
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.c
@@ -0,0 +1,194 @@
1/* $OpenBSD: atexit.c,v 1.17 2013/12/28 18:38:42 kettenis Exp $ */
2/*
3 * Copyright (c) 2002 Daniel Hartmeier
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 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
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 *
30 */
31
32#include <sys/types.h>
33#include <sys/mman.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37#include "atexit.h"
38#include "thread_private.h"
39
40struct atexit *__atexit;
41
42/*
43 * Function pointers are stored in a linked list of pages. The list
44 * is initially empty, and pages are allocated on demand. The first
45 * function pointer in the first allocated page (the last one in
46 * the linked list) is reserved for the cleanup function.
47 *
48 * Outside the following functions, all pages are mprotect()'ed
49 * to prevent unintentional/malicious corruption.
50 */
51
52/*
53 * Register a function to be performed at exit or when a shared object
54 * with the given dso handle is unloaded dynamically. Also used as
55 * the backend for atexit(). For more info on this API, see:
56 *
57 * http://www.codesourcery.com/cxx-abi/abi.html#dso-dtor
58 */
59int
60__cxa_atexit(void (*func)(void *), void *arg, void *dso)
61{
62 struct atexit *p = __atexit;
63 struct atexit_fn *fnp;
64 int pgsize = getpagesize();
65 int ret = -1;
66
67 if (pgsize < sizeof(*p))
68 return (-1);
69 _ATEXIT_LOCK();
70 p = __atexit;
71 if (p != NULL) {
72 if (p->ind + 1 >= p->max)
73 p = NULL;
74 else if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
75 goto unlock;
76 }
77 if (p == NULL) {
78 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
79 MAP_ANON | MAP_PRIVATE, -1, 0);
80 if (p == MAP_FAILED)
81 goto unlock;
82 if (__atexit == NULL) {
83 memset(&p->fns[0], 0, sizeof(p->fns[0]));
84 p->ind = 1;
85 } else
86 p->ind = 0;
87 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
88 sizeof(p->fns[0]);
89 p->next = __atexit;
90 __atexit = p;
91 }
92 fnp = &p->fns[p->ind++];
93 fnp->fn_ptr.cxa_func = func;
94 fnp->fn_arg = arg;
95 fnp->fn_dso = dso;
96 if (mprotect(p, pgsize, PROT_READ))
97 goto unlock;
98 ret = 0;
99unlock:
100 _ATEXIT_UNLOCK();
101 return (ret);
102}
103
104/*
105 * Call all handlers registered with __cxa_atexit() for the shared
106 * object owning 'dso'.
107 * Note: if 'dso' is NULL, then all remaining handlers are called.
108 */
109void
110__cxa_finalize(void *dso)
111{
112 struct atexit *p, *q;
113 struct atexit_fn fn;
114 int n, pgsize = getpagesize();
115 static int call_depth;
116
117 call_depth++;
118
119 for (p = __atexit; p != NULL; p = p->next) {
120 for (n = p->ind; --n >= 0;) {
121 if (p->fns[n].fn_ptr.cxa_func == NULL)
122 continue; /* already called */
123 if (dso != NULL && dso != p->fns[n].fn_dso)
124 continue; /* wrong DSO */
125
126 /*
127 * Mark handler as having been already called to avoid
128 * dupes and loops, then call the appropriate function.
129 */
130 fn = p->fns[n];
131 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) {
132 p->fns[n].fn_ptr.cxa_func = NULL;
133 mprotect(p, pgsize, PROT_READ);
134 }
135 if (fn.fn_dso != NULL)
136 (*fn.fn_ptr.cxa_func)(fn.fn_arg);
137 else
138 (*fn.fn_ptr.std_func)();
139 }
140 }
141
142 call_depth--;
143
144 /*
145 * If called via exit(), unmap the pages since we have now run
146 * all the handlers. We defer this until calldepth == 0 so that
147 * we don't unmap things prematurely if called recursively.
148 */
149 if (dso == NULL && call_depth == 0) {
150 for (p = __atexit; p != NULL; ) {
151 q = p;
152 p = p->next;
153 munmap(q, pgsize);
154 }
155 __atexit = NULL;
156 }
157}
158
159/*
160 * Register the cleanup function
161 */
162void
163__atexit_register_cleanup(void (*func)(void))
164{
165 struct atexit *p;
166 int pgsize = getpagesize();
167
168 if (pgsize < sizeof(*p))
169 return;
170 _ATEXIT_LOCK();
171 p = __atexit;
172 while (p != NULL && p->next != NULL)
173 p = p->next;
174 if (p == NULL) {
175 p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
176 MAP_ANON | MAP_PRIVATE, -1, 0);
177 if (p == MAP_FAILED)
178 goto unlock;
179 p->ind = 1;
180 p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
181 sizeof(p->fns[0]);
182 p->next = NULL;
183 __atexit = p;
184 } else {
185 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
186 goto unlock;
187 }
188 p->fns[0].fn_ptr.std_func = func;
189 p->fns[0].fn_arg = NULL;
190 p->fns[0].fn_dso = NULL;
191 mprotect(p, pgsize, PROT_READ);
192unlock:
193 _ATEXIT_UNLOCK();
194}
diff --git a/src/lib/libc/stdlib/atexit.h b/src/lib/libc/stdlib/atexit.h
new file mode 100644
index 0000000000..c44005deda
--- /dev/null
+++ b/src/lib/libc/stdlib/atexit.h
@@ -0,0 +1,50 @@
1/* $OpenBSD: atexit.h,v 1.8 2013/06/02 21:08:36 matthew Exp $ */
2
3/*
4 * Copyright (c) 2002 Daniel Hartmeier
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33struct atexit {
34 struct atexit *next; /* next in list */
35 int ind; /* next index in this table */
36 int max; /* max entries >= ATEXIT_SIZE */
37 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 */
45};
46
47extern struct atexit *__atexit; /* points to head of LIFO stack */
48
49int __cxa_atexit(void (*)(void *), void *, void *);
50void __cxa_finalize(void *);
diff --git a/src/lib/libc/stdlib/atof.3 b/src/lib/libc/stdlib/atof.3
new file mode 100644
index 0000000000..53722a6253
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.3
@@ -0,0 +1,74 @@
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. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: atof.3,v 1.7 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt ATOF 3
36.Os
37.Sh NAME
38.Nm atof
39.Nd convert
40.Tn ASCII
41string to double
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft double
45.Fn atof "const char *nptr"
46.Sh DESCRIPTION
47The
48.Fn atof
49function converts the initial portion of the string pointed to by
50.Fa nptr
51to
52.Li double
53representation.
54.Pp
55It is equivalent to:
56.Bd -literal -offset indent
57strtod(nptr, (char **)NULL);
58.Ed
59.Sh SEE ALSO
60.Xr atoi 3 ,
61.Xr atol 3 ,
62.Xr strtod 3 ,
63.Xr strtol 3 ,
64.Xr strtoul 3
65.Sh STANDARDS
66The
67.Fn atof
68function conforms to
69.St -ansiC .
70.Sh HISTORY
71An
72.Fn atof
73function first appeared in
74.At v1 .
diff --git a/src/lib/libc/stdlib/atof.c b/src/lib/libc/stdlib/atof.c
new file mode 100644
index 0000000000..d14b58b070
--- /dev/null
+++ b/src/lib/libc/stdlib/atof.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: atof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1988 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33double
34atof(const char *ascii)
35{
36 return(strtod(ascii, (char **)NULL));
37}
diff --git a/src/lib/libc/stdlib/atoi.3 b/src/lib/libc/stdlib/atoi.3
new file mode 100644
index 0000000000..fd5c720e02
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.3
@@ -0,0 +1,91 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: atoi.3,v 1.11 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt ATOI 3
36.Os
37.Sh NAME
38.Nm atoi
39.Nd convert
40.Tn ASCII
41string to integer
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft int
45.Fn atoi "const char *nptr"
46.Sh DESCRIPTION
47The
48.Fn atoi
49function converts the initial portion of the string pointed to by
50.Fa nptr
51to
52.Li integer
53representation.
54.Pp
55It is equivalent to:
56.Bd -literal -offset indent
57(int)strtol(nptr, (char **)NULL, 10);
58.Ed
59.Sh SEE ALSO
60.Xr atof 3 ,
61.Xr atol 3 ,
62.Xr strtod 3 ,
63.Xr strtol 3 ,
64.Xr strtonum 3 ,
65.Xr strtoul 3
66.Sh STANDARDS
67The
68.Fn atoi
69function conforms to
70.St -ansiC .
71.Sh HISTORY
72An
73.Fn atoi
74function first appeared in
75.At v1 .
76.Sh CAVEATS
77.Nm
78does no overflow checking, handles unsigned numbers poorly,
79and handles strings containing trailing extra characters
80(like
81.Dq "123abc" )
82poorly.
83Careful use of
84.Xr strtol 3
85and
86.Xr strtoul 3
87can alleviate these problems,
88but
89.Xr strtonum 3
90can be used to convert numbers from strings much more safely
91and easily.
diff --git a/src/lib/libc/stdlib/atoi.c b/src/lib/libc/stdlib/atoi.c
new file mode 100644
index 0000000000..b0842678e2
--- /dev/null
+++ b/src/lib/libc/stdlib/atoi.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: atoi.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33int
34atoi(const char *str)
35{
36 return((int)strtol(str, (char **)NULL, 10));
37}
diff --git a/src/lib/libc/stdlib/atol.3 b/src/lib/libc/stdlib/atol.3
new file mode 100644
index 0000000000..ae4cbc7c3d
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: atol.3,v 1.8 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt ATOL 3
36.Os
37.Sh NAME
38.Nm atol
39.Nd convert
40.Tn ASCII
41string to long integer
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft long
45.Fn atol "const char *nptr"
46.Sh DESCRIPTION
47The
48.Fn atol
49function converts the initial portion of the string pointed to by
50.Fa nptr
51to
52.Li long integer
53representation.
54.Pp
55It is equivalent to:
56.Bd -literal -offset indent
57strtol(nptr, (char **)NULL, 10);
58.Ed
59.Sh SEE ALSO
60.Xr atof 3 ,
61.Xr atoi 3 ,
62.Xr atoll 3 ,
63.Xr strtod 3 ,
64.Xr strtol 3 ,
65.Xr strtoul 3
66.Sh STANDARDS
67The
68.Fn atol
69function conforms to
70.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/atol.c b/src/lib/libc/stdlib/atol.c
new file mode 100644
index 0000000000..1970804401
--- /dev/null
+++ b/src/lib/libc/stdlib/atol.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: atol.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33long
34atol(const char *str)
35{
36 return(strtol(str, (char **)NULL, 10));
37}
diff --git a/src/lib/libc/stdlib/atoll.3 b/src/lib/libc/stdlib/atoll.3
new file mode 100644
index 0000000000..a9614ae7bb
--- /dev/null
+++ b/src/lib/libc/stdlib/atoll.3
@@ -0,0 +1,70 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: atoll.3,v 1.6 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt ATOLL 3
36.Os
37.Sh NAME
38.Nm atoll
39.Nd convert
40.Tn ASCII
41string to long long integer
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft long long
45.Fn atoll "const char *nptr"
46.Sh DESCRIPTION
47The
48.Fn atoll
49function converts the initial portion of the string pointed to by
50.Fa nptr
51to
52.Li long long integer
53representation.
54.Pp
55It is equivalent to:
56.Bd -literal -offset indent
57strtoll(nptr, (char **)NULL, 10);
58.Ed
59.Sh SEE ALSO
60.Xr atof 3 ,
61.Xr atoi 3 ,
62.Xr atol 3 ,
63.Xr strtod 3 ,
64.Xr strtol 3 ,
65.Xr strtoul 3
66.Sh STANDARDS
67The
68.Fn atoll
69function conforms to
70.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/atoll.c b/src/lib/libc/stdlib/atoll.c
new file mode 100644
index 0000000000..a65e682cfb
--- /dev/null
+++ b/src/lib/libc/stdlib/atoll.c
@@ -0,0 +1,38 @@
1/* $OpenBSD: atoll.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33long long
34atoll(str)
35 const char *str;
36{
37 return(strtoll(str, (char **)NULL, 10));
38}
diff --git a/src/lib/libc/stdlib/bsearch.3 b/src/lib/libc/stdlib/bsearch.3
new file mode 100644
index 0000000000..270086df36
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,84 @@
1.\" Copyright (c) 1990, 1991, 1993, 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: bsearch.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt BSEARCH 3
36.Os
37.Sh NAME
38.Nm bsearch
39.Nd binary search of a sorted table
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft void *
43.Fn bsearch "const void *key" "const void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
44.Sh DESCRIPTION
45The
46.Fn bsearch
47function searches an array of
48.Fa nmemb
49objects, the initial member of which is
50pointed to by
51.Fa base ,
52for a member that matches the object pointed to by
53.Fa key .
54The size of each member of the array is specified by
55.Fa size .
56.Pp
57The contents of the array should be in ascending sorted order according
58to the comparison function referenced by
59.Fa compar .
60The
61.Fa compar
62routine is expected to have two arguments which point to the
63.Fa key
64object and to an array member, in that order, and should return an integer
65less than, equal to, or greater than zero if the
66.Fa key
67object is found, respectively, to be less than, to match, or be
68greater than the array member.
69.Sh RETURN VALUES
70The
71.Fn bsearch
72function returns a pointer to a matching member of the array, or a null
73pointer if no match is found.
74If two members compare as equal, which member is matched is unspecified.
75.Sh SEE ALSO
76.Xr db 3 ,
77.Xr lsearch 3 ,
78.Xr qsort 3 ,
79.Xr tsearch 3
80.Sh STANDARDS
81The
82.Fn bsearch
83function conforms to
84.St -ansiC .
diff --git a/src/lib/libc/stdlib/bsearch.c b/src/lib/libc/stdlib/bsearch.c
new file mode 100644
index 0000000000..b48747236e
--- /dev/null
+++ b/src/lib/libc/stdlib/bsearch.c
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <stdlib.h>
31
32/*
33 * Perform a binary search.
34 *
35 * The code below is a bit sneaky. After a comparison fails, we
36 * divide the work in half by moving either left or right. If lim
37 * is odd, moving left simply involves halving lim: e.g., when lim
38 * is 5 we look at item 2, so we change lim to 2 so that we will
39 * look at items 0 & 1. If lim is even, the same applies. If lim
40 * is odd, moving right again involves halving lim, this time moving
41 * the base up one item past p: e.g., when lim is 5 we change base
42 * to item 3 and make lim 2 so that we will look at items 3 and 4.
43 * If lim is even, however, we have to shrink it by one before
44 * halving: e.g., when lim is 4, we still looked at item 2, so we
45 * have to make lim 3, then halve, obtaining 1, so that we will only
46 * look at item 3.
47 */
48void *
49bsearch(const void *key, const void *base0, size_t nmemb, size_t size,
50 int (*compar)(const void *, const void *))
51{
52 const char *base = base0;
53 int lim, cmp;
54 const void *p;
55
56 for (lim = nmemb; lim != 0; lim >>= 1) {
57 p = base + (lim >> 1) * size;
58 cmp = (*compar)(key, p);
59 if (cmp == 0)
60 return ((void *)p);
61 if (cmp > 0) { /* key > p: move right */
62 base = (char *)p + size;
63 lim--;
64 } /* else move left */
65 }
66 return (NULL);
67}
diff --git a/src/lib/libc/stdlib/cfree.c b/src/lib/libc/stdlib/cfree.c
new file mode 100644
index 0000000000..acf6d1c8ac
--- /dev/null
+++ b/src/lib/libc/stdlib/cfree.c
@@ -0,0 +1,39 @@
1/* $OpenBSD: cfree.c,v 1.6 2012/12/05 23:20:01 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <stdlib.h>
29
30#ifdef __indr_reference
31__indr_reference(free, cfree);
32#else
33
34void
35cfree(void *p)
36{
37 free(p);
38}
39#endif
diff --git a/src/lib/libc/stdlib/div.3 b/src/lib/libc/stdlib/div.3
new file mode 100644
index 0000000000..1a2a326269
--- /dev/null
+++ b/src/lib/libc/stdlib/div.3
@@ -0,0 +1,64 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
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.\" $OpenBSD: div.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt DIV 3
34.Os
35.Sh NAME
36.Nm div
37.Nd return quotient and remainder from division
38.Sh SYNOPSIS
39.In stdlib.h
40.Ft div_t
41.Fn div "int num" "int denom"
42.Sh DESCRIPTION
43The
44.Fn div
45function computes the value
46.Fa num Ns / Ns Fa denom
47and returns the quotient and remainder in a structure named
48.Fa div_t
49that contains two
50.Li int
51members named
52.Fa quot
53and
54.Fa rem .
55.Sh SEE ALSO
56.Xr imaxdiv 3 ,
57.Xr ldiv 3 ,
58.Xr lldiv 3 ,
59.Xr qdiv 3
60.Sh STANDARDS
61The
62.Fn div
63function conforms to
64.St -ansiC .
diff --git a/src/lib/libc/stdlib/div.c b/src/lib/libc/stdlib/div.c
new file mode 100644
index 0000000000..f7ac2db4b0
--- /dev/null
+++ b/src/lib/libc/stdlib/div.c
@@ -0,0 +1,71 @@
1/* $OpenBSD: div.c,v 1.5 2005/08/08 08:05:36 espie 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> /* div_t */
35
36div_t
37div(int num, int denom)
38{
39 div_t r;
40
41 r.quot = num / denom;
42 r.rem = num % denom;
43 /*
44 * The ANSI standard says that |r.quot| <= |n/d|, where
45 * n/d is to be computed in infinite precision. In other
46 * words, we should always truncate the quotient towards
47 * 0, never -infinity.
48 *
49 * Machine division and remainer may work either way when
50 * one or both of n or d is negative. If only one is
51 * negative and r.quot has been truncated towards -inf,
52 * r.rem will have the same sign as denom and the opposite
53 * sign of num; if both are negative and r.quot has been
54 * truncated towards -inf, r.rem will be positive (will
55 * have the opposite sign of num). These are considered
56 * `wrong'.
57 *
58 * If both are num and denom are positive, r will always
59 * be positive.
60 *
61 * This all boils down to:
62 * if num >= 0, but r.rem < 0, we got the wrong answer.
63 * In that case, to get the right answer, add 1 to r.quot and
64 * subtract denom from r.rem.
65 */
66 if (num >= 0 && r.rem < 0) {
67 r.quot++;
68 r.rem -= denom;
69 }
70 return (r);
71}
diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c
new file mode 100644
index 0000000000..b6c046c831
--- /dev/null
+++ b/src/lib/libc/stdlib/drand48.c
@@ -0,0 +1,23 @@
1/* $OpenBSD: drand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18
19double
20drand48(void)
21{
22 return erand48(__rand48_seed);
23}
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3
new file mode 100644
index 0000000000..d8a3489b1f
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,168 @@
1.\" $OpenBSD: ecvt.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.\" Sponsored in part by the Defense Advanced Research Projects
18.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
19.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
20.\"
21.Dd $Mdocdate: June 5 2013 $
22.Dt ECVT 3
23.Os
24.Sh NAME
25.Nm ecvt ,
26.Nm fcvt ,
27.Nm gcvt
28.Nd convert double to
29.Tn ASCII
30string
31.Sh SYNOPSIS
32.In stdlib.h
33.Ft char *
34.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
35.Ft char *
36.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
37.Ft char *
38.Fn gcvt "double value" "int ndigit" "char *buf"
39.Sh DESCRIPTION
40.Bf -symbolic
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 SEE ALSO
142.Xr printf 3 ,
143.Xr strtod 3
144.Sh STANDARDS
145The
146.Fn ecvt ,
147.Fn fcvt
148and
149.Fn gcvt
150functions conform to
151.St -p1003.1-2001 ;
152as of
153.St -p1003.1-2008
154they are no longer a part of the standard.
155.Sh CAVEATS
156The
157.Fn ecvt
158and
159.Fn fcvt
160functions return a pointer to internal storage space that will be
161overwritten by subsequent calls to either function.
162.Pp
163The maximum possible precision of the return value is limited by the
164precision of a double and may not be the same on all architectures.
165.Pp
166The
167.Xr snprintf 3
168function is preferred over these functions for new code.
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c
new file mode 100644
index 0000000000..4562e309e8
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: ecvt.c,v 1.8 2013/11/01 19:05:11 guenther Exp $ */
2
3/*
4 * Copyright (c) 2002, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include "gdtoa.h"
27
28static char *__cvt(double, int, int *, int *, int, int);
29
30static char *
31__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
32{
33 static char *s;
34 char *p, *rve, c;
35 size_t siz;
36
37 if (ndigit == 0) {
38 *sign = value < 0.0;
39 *decpt = 0;
40 return ("");
41 }
42
43 if (s) {
44 free(s);
45 s = NULL;
46 }
47
48 if (ndigit < 0)
49 siz = -ndigit + 1;
50 else
51 siz = ndigit + 1;
52
53
54 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
55 if (value == 0.0) {
56 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
57 *sign = 0;
58 if ((rve = s = (char *)malloc(siz)) == NULL)
59 return(NULL);
60 *rve++ = '0';
61 *rve = '\0';
62 } else {
63 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
64 if (p == NULL)
65 return (NULL);
66 if (*decpt == 9999) {
67 /* Infinity or Nan, convert to inf or nan like printf */
68 *decpt = 0;
69 c = *p;
70 __freedtoa(p);
71 return(c == 'I' ? "inf" : "nan");
72 }
73 /* Make a local copy and adjust rve to be in terms of s */
74 if (pad && fmode)
75 siz += *decpt;
76 if ((s = (char *)malloc(siz)) == NULL) {
77 __freedtoa(p);
78 return(NULL);
79 }
80 (void) strlcpy(s, p, siz);
81 rve = s + (rve - p);
82 __freedtoa(p);
83 }
84
85 /* Add trailing zeros */
86 if (pad) {
87 siz -= rve - s;
88 while (--siz)
89 *rve++ = '0';
90 *rve = '\0';
91 }
92
93 return(s);
94}
95
96char *
97ecvt(double value, int ndigit, int *decpt, int *sign)
98{
99 return(__cvt(value, ndigit, decpt, sign, 0, 1));
100}
101
102char *
103fcvt(double value, int ndigit, int *decpt, int *sign)
104{
105 return(__cvt(value, ndigit, decpt, sign, 1, 1));
106}
diff --git a/src/lib/libc/stdlib/erand48.c b/src/lib/libc/stdlib/erand48.c
new file mode 100644
index 0000000000..2ffeaa6e71
--- /dev/null
+++ b/src/lib/libc/stdlib/erand48.c
@@ -0,0 +1,24 @@
1/* $OpenBSD: erand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17double
18erand48(unsigned short xseed[3])
19{
20 __dorand48(xseed);
21 return ldexp((double) xseed[0], -48) +
22 ldexp((double) xseed[1], -32) +
23 ldexp((double) xseed[2], -16);
24}
diff --git a/src/lib/libc/stdlib/exit.3 b/src/lib/libc/stdlib/exit.3
new file mode 100644
index 0000000000..26922ca7b8
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.3
@@ -0,0 +1,102 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: exit.3,v 1.15 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt EXIT 3
36.Os
37.Sh NAME
38.Nm exit
39.Nd perform normal program termination
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft void
43.Fn exit "int status"
44.Sh DESCRIPTION
45The
46.Fn exit
47function terminates a process.
48.Pp
49Before termination it performs the following functions in the
50order listed:
51.Bl -enum -offset indent
52.It
53Call the functions registered with the
54.Xr atexit 3
55function, in the reverse order of their registration.
56.It
57Flush all open output streams.
58.It
59Close all open streams.
60.It
61Unlink all files created with the
62.Xr tmpfile 3
63function.
64.El
65.Pp
66Following this,
67.Fn exit
68calls
69.Xr _exit 2 .
70Note that typically
71.Xr _exit 2
72only passes the lower 8 bits of
73.Fa status
74on to the parent, thus negative values have less meaning.
75.Sh RETURN VALUES
76The
77.Fn exit
78function never returns.
79.Sh SEE ALSO
80.Xr _exit 2 ,
81.Xr atexit 3 ,
82.Xr intro 3 ,
83.Xr sysexits 3 ,
84.Xr tmpfile 3
85.Sh STANDARDS
86The
87.Fn exit
88function conforms to
89.St -ansiC-99 .
90.Sh HISTORY
91An
92.Fn exit
93function first appeared as a system call in
94.At v1 .
95It has accepted the
96.Fa status
97argument since
98.At v2 .
99In
100.At v7 ,
101the bare system call was renamed to
102.Xr _exit 2 .
diff --git a/src/lib/libc/stdlib/exit.c b/src/lib/libc/stdlib/exit.c
new file mode 100644
index 0000000000..83fe3d2de5
--- /dev/null
+++ b/src/lib/libc/stdlib/exit.c
@@ -0,0 +1,59 @@
1/* $OpenBSD: exit.c,v 1.12 2007/09/03 14:40:16 millert Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/types.h>
32#include <sys/mman.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include "atexit.h"
36#include "thread_private.h"
37
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;
46
47/*
48 * Exit, flushing stdio buffers if necessary.
49 */
50void
51exit(int status)
52{
53 /*
54 * Call functions registered by atexit() or _cxa_atexit()
55 * (including the stdio cleanup routine) and then _exit().
56 */
57 __cxa_finalize(NULL);
58 _exit(status);
59}
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..f233332799
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,123 @@
1/* $OpenBSD: gcvt.c,v 1.13 2013/11/01 19:05:11 guenther Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003, 2006, 2010
5 * Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Sponsored in part by the Defense Advanced Research Projects
20 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22 */
23
24#include <locale.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include "gdtoa.h"
29
30#define DEFPREC 6
31
32char *
33gcvt(double value, int ndigit, char *buf)
34{
35 char *digits, *dst, *src;
36 int i, decpt, sign;
37 struct lconv *lconv;
38
39 lconv = localeconv();
40 if (ndigit <= 0) {
41 /* Match printf(3) behavior. */
42 ndigit = ndigit ? DEFPREC : 1;
43 }
44
45 digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
46 if (digits == NULL)
47 return (NULL);
48 if (decpt == 9999) {
49 /*
50 * Infinity or NaN, convert to inf or nan with sign.
51 * We can't infer buffer size based on ndigit.
52 * We have to assume it is at least 5 chars.
53 */
54 snprintf(buf, 5, "%s%s", sign ? "-" : "",
55 *digits == 'I' ? "inf" : "nan");
56 __freedtoa(digits);
57 return (buf);
58 }
59
60 dst = buf;
61 if (sign)
62 *dst++ = '-';
63
64 /* Match printf(3) behavior for exponential vs. regular fomatting. */
65 if (decpt <= -4 || decpt > ndigit) {
66 /* exponential format (e.g. 1.2345e+13) */
67 if (--decpt < 0) {
68 sign = 1;
69 decpt = -decpt;
70 } else
71 sign = 0;
72 src = digits;
73 *dst++ = *src++;
74 if (*src != '\0') {
75 *dst++ = *lconv->decimal_point;
76 do {
77 *dst++ = *src++;
78 } while (*src != '\0');
79 }
80 *dst++ = 'e';
81 if (sign)
82 *dst++ = '-';
83 else
84 *dst++ = '+';
85 if (decpt < 10) {
86 *dst++ = '0';
87 *dst++ = '0' + decpt;
88 *dst = '\0';
89 } else {
90 /* XXX - optimize */
91 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
92 continue;
93 dst[i + 1] = '\0';
94 while (decpt != 0) {
95 dst[i--] = '0' + decpt % 10;
96 decpt /= 10;
97 }
98 }
99 } else {
100 /* standard format */
101 for (i = 0, src = digits; i < decpt; i++) {
102 if (*src != '\0')
103 *dst++ = *src++;
104 else
105 *dst++ = '0';
106 }
107 if (*src != '\0') {
108 if (src == digits)
109 *dst++ = '0'; /* zero before decimal point */
110 *dst++ = *lconv->decimal_point;
111 while (decpt < 0) {
112 *dst++ = '0';
113 decpt++;
114 }
115 for (i = decpt; digits[i] != '\0'; i++) {
116 *dst++ = digits[i];
117 }
118 }
119 *dst = '\0';
120 }
121 __freedtoa(digits);
122 return (buf);
123}
diff --git a/src/lib/libc/stdlib/getenv.3 b/src/lib/libc/stdlib/getenv.3
new file mode 100644
index 0000000000..5239d1b0d5
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.3
@@ -0,0 +1,175 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: getenv.3,v 1.19 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt GETENV 3
36.Os
37.Sh NAME
38.Nm getenv ,
39.Nm putenv ,
40.Nm setenv ,
41.Nm unsetenv
42.Nd environment variable functions
43.Sh SYNOPSIS
44.In stdlib.h
45.Ft char *
46.Fn getenv "const char *name"
47.Ft int
48.Fn setenv "const char *name" "const char *value" "int overwrite"
49.Ft int
50.Fn putenv "char *string"
51.Ft int
52.Fn unsetenv "const char *name"
53.Sh DESCRIPTION
54These functions set, unset, and fetch environment variables from the host
55.Em environment list .
56.Pp
57The
58.Fn getenv
59function obtains the current value of the environment variable
60.Fa name .
61If the variable
62.Fa name
63is not in the current environment, a null pointer is returned.
64.Pp
65The
66.Fn setenv
67function inserts or resets the environment variable
68.Fa name
69in the current environment list.
70If the variable
71.Fa name
72does not exist in the list, it is inserted with the given
73.Fa value .
74If the variable does exist, the argument
75.Fa overwrite
76is tested; if
77.Fa overwrite
78is zero, the variable is not reset, otherwise it is reset to the given
79.Fa value .
80.Pp
81The
82.Fn putenv
83function takes an argument of the form
84.Ar name Ns = Ns Ar value .
85The memory pointed to by
86.Ar string
87becomes part of the environment and must not be deallocated by the caller.
88If the variable already exists, it will be overwritten.
89A common source of bugs is to pass a
90.Ar string
91argument that is a locally scoped string buffer.
92This will result in corruption of the environment after leaving
93the scope in which the variable is defined.
94For this reason, the
95.Fn setenv
96function is preferred over
97.Fn putenv .
98.Pp
99The
100.Fn unsetenv
101function deletes all instances of the variable name pointed to by
102.Fa name
103from the list.
104.Sh RETURN VALUES
105These functions
106return zero if successful; otherwise the global variable
107.Va errno
108is set to indicate the error and \-1 is returned.
109.Pp
110If
111.Fn getenv
112is successful, the string returned should be considered read-only.
113.Sh ERRORS
114.Bl -tag -width Er
115.It Bq Er EINVAL
116The
117.Fn setenv
118or
119.Fn unsetenv
120function was passed an empty
121.Ar name
122or a NULL pointer, or was passed a
123.Ar name
124containing an
125.Sq =
126character.
127.Pp
128The
129.Fn putenv
130function was passed a
131.Ar string
132that did not contain an
133.Sq =
134character.
135.It Bq Er ENOMEM
136The
137.Fn setenv
138or
139.Fn putenv
140function failed because it was unable to allocate memory for the environment.
141.El
142.Sh SEE ALSO
143.Xr csh 1 ,
144.Xr sh 1 ,
145.Xr execve 2 ,
146.Xr environ 7
147.Sh STANDARDS
148The
149.Fn getenv
150function conforms to
151.St -ansiC .
152The
153.Fn putenv ,
154.Fn setenv ,
155and
156.Fn unsetenv
157functions conform to
158.St -p1003.1-2008 .
159.Sh HISTORY
160The function
161.Fn getenv
162appeared in
163.At v7
164and
165.Bx 3 .
166The functions
167.Fn setenv
168and
169.Fn unsetenv
170appeared in
171.Bx 4.3 Tahoe .
172The
173.Fn putenv
174function appeared in
175.Bx 4.3 Reno .
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
new file mode 100644
index 0000000000..fd8482e9e3
--- /dev/null
+++ b/src/lib/libc/stdlib/getenv.c
@@ -0,0 +1,81 @@
1/* $OpenBSD: getenv.c,v 1.10 2010/08/23 22:31:50 millert Exp $ */
2/*
3 * Copyright (c) 1987, 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
31#include <stdlib.h>
32#include <string.h>
33
34char *__findenv(const char *name, int len, int *offset);
35
36/*
37 * __findenv --
38 * Returns pointer to value associated with name, if any, else NULL.
39 * Starts searching within the environmental array at offset.
40 * Sets offset to be the offset of the name/value combination in the
41 * environmental array, for use by putenv(3), setenv(3) and unsetenv(3).
42 * Explicitly removes '=' in argument name.
43 *
44 * This routine *should* be a static; don't use it.
45 */
46char *
47__findenv(const char *name, int len, int *offset)
48{
49 extern char **environ;
50 int i;
51 const char *np;
52 char **p, *cp;
53
54 if (name == NULL || environ == NULL)
55 return (NULL);
56 for (p = environ + *offset; (cp = *p) != NULL; ++p) {
57 for (np = name, i = len; i && *cp; i--)
58 if (*cp++ != *np++)
59 break;
60 if (i == 0 && *cp++ == '=') {
61 *offset = p - environ;
62 return (cp);
63 }
64 }
65 return (NULL);
66}
67
68/*
69 * getenv --
70 * Returns ptr to value associated with name, if any, else NULL.
71 */
72char *
73getenv(const char *name)
74{
75 int offset = 0;
76 const char *np;
77
78 for (np = name; *np && *np != '='; ++np)
79 ;
80 return (__findenv(name, (int)(np - name), &offset));
81}
diff --git a/src/lib/libc/stdlib/getopt.3 b/src/lib/libc/stdlib/getopt.3
new file mode 100644
index 0000000000..6661e03841
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt.3
@@ -0,0 +1,364 @@
1.\" Copyright (c) 1988, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $OpenBSD: getopt.3,v 1.44 2014/01/21 03:15:45 schwarze Exp $
29.\"
30.Dd $Mdocdate: January 21 2014 $
31.Dt GETOPT 3
32.Os
33.Sh NAME
34.Nm getopt
35.Nd get option character from command line argument list
36.Sh SYNOPSIS
37.In unistd.h
38.Vt extern char *optarg;
39.Vt extern int opterr;
40.Vt extern int optind;
41.Vt extern int optopt;
42.Vt extern int optreset;
43.Ft int
44.Fn getopt "int argc" "char * const *argv" "const char *optstring"
45.Sh DESCRIPTION
46The
47.Fn getopt
48function incrementally parses a command line argument list
49.Fa argv
50and returns the next
51.Em known
52option character.
53An option character is
54.Em known
55if it has been specified in the string of accepted option characters,
56.Fa optstring .
57.Pp
58The option string
59.Fa optstring
60may contain the following elements: individual characters,
61characters followed by a colon, and characters followed by two colons.
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.
66For example, an option string
67.Qq x
68recognizes an option
69.Fl x ,
70and an option string
71.Qq Li x:
72recognizes an option and argument
73.Fl x Ar argument .
74It does not matter to
75.Fn getopt
76if a following argument has leading whitespace; except in the case where
77the argument is optional, denoted with two colons, no leading whitespace
78is permitted.
79.Pp
80On return from
81.Fn getopt ,
82.Va optarg
83points to an option argument, if it is anticipated,
84and the variable
85.Va optind
86contains the index to the next
87.Fa argv
88argument for a subsequent call
89to
90.Fn getopt .
91.Pp
92The variables
93.Va opterr
94and
95.Va optind
96are both initialized to 1.
97The
98.Va optind
99variable may be set to another value larger than 0 before a set of calls to
100.Fn getopt
101in order to skip over more or less
102.Fa argv
103entries.
104An
105.Va optind
106value of 0 is reserved for compatibility with GNU
107.Fn getopt .
108.Pp
109In order to use
110.Fn getopt
111to evaluate multiple sets of arguments, or to evaluate a single set of
112arguments multiple times,
113the variable
114.Va optreset
115must be set to 1 before the second and each additional set of calls to
116.Fn getopt ,
117and the variable
118.Va optind
119must be reinitialized.
120.Pp
121The
122.Fn getopt
123function returns \-1 when the argument list is exhausted.
124The interpretation of options in the argument list may be cancelled
125by the option
126.Ql --
127(double dash) which causes
128.Fn getopt
129to signal the end of argument processing and return \-1.
130When all options have been processed (i.e., up to the first non-option
131argument),
132.Fn getopt
133returns \-1.
134.Sh RETURN VALUES
135The
136.Fn getopt
137function returns the next known option character in
138.Fa optstring .
139If
140.Fn getopt
141encounters a character not found in
142.Fa optstring
143or if it detects a missing option argument,
144it returns
145.Sq \&?
146(question mark).
147If
148.Fa optstring
149has a leading
150.Sq \&:
151then a missing option argument causes
152.Sq \&:
153to be returned instead of
154.Sq \&? .
155In either case, the variable
156.Va optopt
157is set to the character that caused the error.
158The
159.Fn getopt
160function returns \-1 when the argument list is exhausted.
161.Sh EXAMPLES
162The following code accepts the options
163.Fl b
164and
165.Fl f Ar argument
166and adjusts
167.Va argc
168and
169.Va argv
170after option argument processing has completed.
171.Bd -literal -offset indent
172int bflag, ch, fd;
173
174bflag = 0;
175while ((ch = getopt(argc, argv, "bf:")) != -1) {
176 switch (ch) {
177 case 'b':
178 bflag = 1;
179 break;
180 case 'f':
181 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
182 err(1, "%s", optarg);
183 break;
184 default:
185 usage();
186 /* NOTREACHED */
187 }
188}
189argc -= optind;
190argv += optind;
191.Ed
192.Sh DIAGNOSTICS
193If the
194.Fn getopt
195function encounters a character not found in the string
196.Fa optstring
197or detects
198a missing option argument, it writes an error message to
199.Em stderr
200and returns
201.Ql \&? .
202Setting
203.Va opterr
204to a zero will disable these error messages.
205If
206.Fa optstring
207has a leading
208.Ql \&:
209then a missing option argument causes a
210.Ql \&:
211to be returned in addition to suppressing any error messages.
212.Pp
213Option arguments are allowed to begin with
214.Ql - ;
215this is reasonable but reduces the amount of error checking possible.
216.Sh SEE ALSO
217.Xr getopt 1 ,
218.Xr getopt_long 3 ,
219.Xr getsubopt 3
220.Sh STANDARDS
221The
222.Fn getopt
223function implements a superset of the functionality specified by
224.St -p1003.1 .
225.Pp
226The following extensions are supported:
227.Bl -tag -width "xxx"
228.It Li o
229The
230.Va optreset
231variable was added to make it possible to call the
232.Fn getopt
233function multiple times.
234.It Li o
235If the
236.Va optind
237variable is set to 0,
238.Fn getopt
239will behave as if the
240.Va optreset
241variable has been set.
242This is for compatibility with
243.Tn GNU
244.Fn getopt .
245New code should use
246.Va optreset
247instead.
248.It Li o
249If the first character of
250.Fa optstring
251is a plus sign
252.Pq Ql + ,
253it will be ignored.
254This is for compatibility with
255.Tn GNU
256.Fn getopt .
257.It Li o
258If the first character of
259.Fa optstring
260is a dash
261.Pq Ql - ,
262non-options will be returned as arguments to the option character
263.Ql \e1 .
264This is for compatibility with
265.Tn GNU
266.Fn getopt .
267.It Li o
268A single dash
269.Pq Ql -
270may be specified as a character in
271.Fa optstring ,
272however it should
273.Em never
274have an argument associated with it.
275This allows
276.Fn getopt
277to be used with programs that expect
278.Ql -
279as an option flag.
280This practice is wrong, and should not be used in any current development.
281It is provided for backward compatibility
282.Em only .
283Care should be taken not to use
284.Ql -
285as the first character in
286.Fa optstring
287to avoid a semantic conflict with
288.Tn GNU
289.Fn getopt
290semantics (see above).
291By default, a single dash causes
292.Fn getopt
293to return \-1.
294.El
295.Pp
296Historic
297.Bx
298versions of
299.Fn getopt
300set
301.Fa optopt
302to the last option character processed.
303However, this conflicts with
304.St -p1003.1
305which stipulates that
306.Fa optopt
307be set to the last character that caused an error.
308.Sh HISTORY
309The
310.Fn getopt
311function appeared in
312.Bx 4.3 .
313.Sh BUGS
314The
315.Fn getopt
316function was once specified to return
317.Dv EOF
318instead of \-1.
319This was changed by
320.St -p1003.2-92
321to decouple
322.Fn getopt
323from
324.In stdio.h .
325.Pp
326It is possible to handle digits as option letters.
327This allows
328.Fn getopt
329to be used with programs that expect a number
330.Pq Dq Li \-3
331as an option.
332This practice is wrong, and should not be used in any current development.
333It is provided for backward compatibility
334.Em only .
335The following code fragment works in most cases and can handle mixed
336number and letter arguments.
337.Bd -literal -offset indent
338int aflag = 0, bflag = 0, ch, lastch = '\e0';
339int length = -1, newarg = 1, prevoptind = 1;
340
341while ((ch = getopt(argc, argv, "0123456789ab")) != -1) {
342 switch (ch) {
343 case '0': case '1': case '2': case '3': case '4':
344 case '5': case '6': case '7': case '8': case '9':
345 if (newarg || !isdigit(lastch))
346 length = 0;
347 else if (length > INT_MAX / 10)
348 usage();
349 length = (length * 10) + (ch - '0');
350 break;
351 case 'a':
352 aflag = 1;
353 break;
354 case 'b':
355 bflag = 1;
356 break;
357 default:
358 usage();
359 }
360 lastch = ch;
361 newarg = optind != prevoptind;
362 prevoptind = optind;
363}
364.Ed
diff --git a/src/lib/libc/stdlib/getopt_long.3 b/src/lib/libc/stdlib/getopt_long.3
new file mode 100644
index 0000000000..a5973d6c99
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.3
@@ -0,0 +1,445 @@
1.\" $OpenBSD: getopt_long.3,v 1.20 2013/06/05 03:39:23 tedu Exp $
2.\" $NetBSD: getopt_long.3,v 1.11 2002/10/02 10:54:19 wiz Exp $
3.\"
4.\" Copyright (c) 1988, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the University nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.\" @(#)getopt.3 8.5 (Berkeley) 4/27/95
32.\"
33.Dd $Mdocdate: June 5 2013 $
34.Dt GETOPT_LONG 3
35.Os
36.Sh NAME
37.Nm getopt_long ,
38.Nm getopt_long_only
39.Nd get long options from command line argument list
40.Sh SYNOPSIS
41.In getopt.h
42.Vt extern char *optarg;
43.Vt extern int optind;
44.Vt extern int optopt;
45.Vt extern int opterr;
46.Vt extern int optreset;
47.Ft int
48.Fn getopt_long "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
49.Ft int
50.Fn getopt_long_only "int argc" "char * const *argv" "const char *optstring" "const struct option *longopts" "int *longindex"
51.Sh DESCRIPTION
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 an array to be initialized describing the long
104options.
105Each element of the array is a structure:
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 IMPLEMENTATION DIFFERENCES
208This section describes differences to the GNU implementation
209found in glibc-2.1.3:
210.Bl -bullet
211.It
212handling of
213.Ql -
214within the option string (not the first character):
215.Bl -tag -width "OpenBSD"
216.It GNU
217treats a
218.Ql -
219on the command line as a non-argument.
220.It OpenBSD
221a
222.Ql -
223within the option string matches a
224.Ql -
225(single dash) on the command line.
226This functionality is provided for backward compatibility with
227programs, such as
228.Xr su 1 ,
229that use
230.Ql -
231as an option flag.
232This practice is wrong, and should not be used in any current development.
233.El
234.It
235handling of
236.Ql ::
237in the option string in the presence of
238.Ev POSIXLY_CORRECT :
239.Bl -tag -width "OpenBSD"
240.It Both
241GNU and
242.Ox
243ignore
244.Ev POSIXLY_CORRECT
245here and take
246.Ql ::
247to mean the preceding option takes an optional argument.
248.El
249.It
250return value in case of missing argument if first character
251(after
252.Ql +
253or
254.Ql - )
255in the option string is not
256.Ql \&: :
257.Bl -tag -width "OpenBSD"
258.It GNU
259returns
260.Ql \&?
261.It OpenBSD
262returns
263.Ql \&:
264(since
265.Ox Ns 's
266.Xr getopt 3
267does).
268.El
269.It
270handling of
271.Ql --a
272in
273.Xr getopt 3 :
274.Bl -tag -width "OpenBSD"
275.It GNU
276parses this as option
277.Ql - ,
278option
279.Ql a .
280.It OpenBSD
281parses this as
282.Ql -- ,
283and returns \-1 (ignoring the
284.Ql a )
285(because the original
286.Fn getopt
287did.)
288.El
289.It
290setting of
291.Va optopt
292for long options with
293.Va flag
294.No non- Ns Dv NULL :
295.Bl -tag -width "OpenBSD"
296.It GNU
297sets
298.Va optopt
299to
300.Va val .
301.It OpenBSD
302sets
303.Va optopt
304to 0 (since
305.Va val
306would never be returned).
307.El
308.It
309handling of
310.Ql -W
311with
312.Ql W;
313in the option string in
314.Xr getopt 3
315(not
316.Fn getopt_long ) :
317.Bl -tag -width "OpenBSD"
318.It GNU
319causes a segmentation fault.
320.It OpenBSD
321no special handling is done;
322.Ql W;
323is interpreted as two separate options, neither of which take an argument.
324.El
325.It
326setting of
327.Va optarg
328for long options without an argument that are invoked via
329.Ql -W
330(with
331.Ql W;
332in the option string):
333.Bl -tag -width "OpenBSD"
334.It GNU
335sets
336.Va optarg
337to the option name (the argument of
338.Ql -W ) .
339.It OpenBSD
340sets
341.Va optarg
342to
343.Dv NULL
344(the argument of the long option).
345.El
346.It
347handling of
348.Ql -W
349with an argument that is not (a prefix to) a known long option
350(with
351.Ql W;
352in the option string):
353.Bl -tag -width "OpenBSD"
354.It GNU
355returns
356.Ql -W
357with
358.Va optarg
359set to the unknown option.
360.It OpenBSD
361treats this as an error (unknown option) and returns
362.Ql \&?
363with
364.Va optopt
365set to 0 and
366.Va optarg
367set to
368.Dv NULL
369(as GNU's man page documents).
370.El
371.It
372The error messages are different.
373.It
374.Ox
375does not permute the argument vector at the same points in
376the calling sequence as GNU does.
377The aspects normally used by the caller
378(ordering after \-1 is returned, value of
379.Va optind
380relative to current positions) are the same, though.
381(We do fewer variable swaps.)
382.El
383.Sh ENVIRONMENT
384.Bl -tag -width Ev
385.It Ev POSIXLY_CORRECT
386If set, option processing stops when the first non-option is found and
387a leading
388.Sq +
389in the
390.Ar optstring
391is ignored.
392.El
393.Sh EXAMPLES
394.Bd -literal
395int bflag, ch, fd;
396int daggerset;
397
398/* options descriptor */
399static struct option longopts[] = {
400 { "buffy", no_argument, NULL, 'b' },
401 { "fluoride", required_argument, NULL, 'f' },
402 { "daggerset", no_argument, &daggerset, 1 },
403 { NULL, 0, NULL, 0 }
404};
405
406bflag = 0;
407while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1)
408 switch (ch) {
409 case 'b':
410 bflag = 1;
411 break;
412 case 'f':
413 if ((fd = open(optarg, O_RDONLY, 0)) == -1)
414 err(1, "unable to open %s", optarg);
415 break;
416 case 0:
417 if (daggerset)
418 fprintf(stderr, "Buffy will use her dagger to "
419 "apply fluoride to dracula's teeth\en");
420 break;
421 default:
422 usage();
423 /* NOTREACHED */
424 }
425argc -= optind;
426argv += optind;
427.Ed
428.Sh SEE ALSO
429.Xr getopt 3
430.Sh HISTORY
431The
432.Fn getopt_long
433and
434.Fn getopt_long_only
435functions first appeared in GNU libiberty.
436This implementation first appeared in
437.Ox 3.3 .
438.Sh BUGS
439The
440.Ar argv
441argument is not really
442.Dv const
443as its elements may be permuted (unless
444.Ev POSIXLY_CORRECT
445is set).
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c
new file mode 100644
index 0000000000..f46cd8bf4e
--- /dev/null
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -0,0 +1,518 @@
1/* $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $ */
2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
3
4/*
5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Sponsored in part by the Defense Advanced Research Projects
20 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22 */
23/*-
24 * Copyright (c) 2000 The NetBSD Foundation, Inc.
25 * All rights reserved.
26 *
27 * This code is derived from software contributed to The NetBSD Foundation
28 * by Dieter Baron and Thomas Klausner.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
40 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
43 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 * POSSIBILITY OF SUCH DAMAGE.
50 */
51
52#include <err.h>
53#include <errno.h>
54#include <getopt.h>
55#include <stdlib.h>
56#include <string.h>
57
58int opterr = 1; /* if error message should be printed */
59int optind = 1; /* index into parent argv vector */
60int optopt = '?'; /* character checked for validity */
61int optreset; /* reset getopt */
62char *optarg; /* argument associated with option */
63
64#define PRINT_ERROR ((opterr) && (*options != ':'))
65
66#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
67#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
68#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
69
70/* return values */
71#define BADCH (int)'?'
72#define BADARG ((*options == ':') ? (int)':' : (int)'?')
73#define INORDER (int)1
74
75#define EMSG ""
76
77static int getopt_internal(int, char * const *, const char *,
78 const struct option *, int *, int);
79static int parse_long_options(char * const *, const char *,
80 const struct option *, int *, int, int);
81static int gcd(int, int);
82static void permute_args(int, int, int, char * const *);
83
84static char *place = EMSG; /* option letter processing */
85
86/* XXX: set optreset to 1 rather than these two */
87static int nonopt_start = -1; /* first non option argument (for permute) */
88static int nonopt_end = -1; /* first option after non options (for permute) */
89
90/* Error messages */
91static const char recargchar[] = "option requires an argument -- %c";
92static const char recargstring[] = "option requires an argument -- %s";
93static const char ambig[] = "ambiguous option -- %.*s";
94static const char noarg[] = "option doesn't take an argument -- %.*s";
95static const char illoptchar[] = "unknown option -- %c";
96static const char illoptstring[] = "unknown option -- %s";
97
98/*
99 * Compute the greatest common divisor of a and b.
100 */
101static int
102gcd(int a, int b)
103{
104 int c;
105
106 c = a % b;
107 while (c != 0) {
108 a = b;
109 b = c;
110 c = a % b;
111 }
112
113 return (b);
114}
115
116/*
117 * Exchange the block from nonopt_start to nonopt_end with the block
118 * from nonopt_end to opt_end (keeping the same order of arguments
119 * in each block).
120 */
121static void
122permute_args(int panonopt_start, int panonopt_end, int opt_end,
123 char * const *nargv)
124{
125 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
126 char *swap;
127
128 /*
129 * compute lengths of blocks and number and size of cycles
130 */
131 nnonopts = panonopt_end - panonopt_start;
132 nopts = opt_end - panonopt_end;
133 ncycle = gcd(nnonopts, nopts);
134 cyclelen = (opt_end - panonopt_start) / ncycle;
135
136 for (i = 0; i < ncycle; i++) {
137 cstart = panonopt_end+i;
138 pos = cstart;
139 for (j = 0; j < cyclelen; j++) {
140 if (pos >= panonopt_end)
141 pos -= nnonopts;
142 else
143 pos += nopts;
144 swap = nargv[pos];
145 /* LINTED const cast */
146 ((char **) nargv)[pos] = nargv[cstart];
147 /* LINTED const cast */
148 ((char **)nargv)[cstart] = swap;
149 }
150 }
151}
152
153/*
154 * parse_long_options --
155 * Parse long options in argc/argv argument vector.
156 * Returns -1 if short_too is set and the option does not match long_options.
157 */
158static int
159parse_long_options(char * const *nargv, const char *options,
160 const struct option *long_options, int *idx, int short_too, int flags)
161{
162 char *current_argv, *has_equal;
163 size_t current_argv_len;
164 int i, match, exact_match, second_partial_match;
165
166 current_argv = place;
167 match = -1;
168 exact_match = 0;
169 second_partial_match = 0;
170
171 optind++;
172
173 if ((has_equal = strchr(current_argv, '=')) != NULL) {
174 /* argument found (--option=arg) */
175 current_argv_len = has_equal - current_argv;
176 has_equal++;
177 } else
178 current_argv_len = strlen(current_argv);
179
180 for (i = 0; long_options[i].name; i++) {
181 /* find matching long option */
182 if (strncmp(current_argv, long_options[i].name,
183 current_argv_len))
184 continue;
185
186 if (strlen(long_options[i].name) == current_argv_len) {
187 /* exact match */
188 match = i;
189 exact_match = 1;
190 break;
191 }
192 /*
193 * If this is a known short option, don't allow
194 * a partial match of a single character.
195 */
196 if (short_too && current_argv_len == 1)
197 continue;
198
199 if (match == -1) /* first partial match */
200 match = i;
201 else if ((flags & FLAG_LONGONLY) ||
202 long_options[i].has_arg != long_options[match].has_arg ||
203 long_options[i].flag != long_options[match].flag ||
204 long_options[i].val != long_options[match].val)
205 second_partial_match = 1;
206 }
207 if (!exact_match && second_partial_match) {
208 /* ambiguous abbreviation */
209 if (PRINT_ERROR)
210 warnx(ambig, (int)current_argv_len, current_argv);
211 optopt = 0;
212 return (BADCH);
213 }
214 if (match != -1) { /* option found */
215 if (long_options[match].has_arg == no_argument
216 && has_equal) {
217 if (PRINT_ERROR)
218 warnx(noarg, (int)current_argv_len,
219 current_argv);
220 /*
221 * XXX: GNU sets optopt to val regardless of flag
222 */
223 if (long_options[match].flag == NULL)
224 optopt = long_options[match].val;
225 else
226 optopt = 0;
227 return (BADARG);
228 }
229 if (long_options[match].has_arg == required_argument ||
230 long_options[match].has_arg == optional_argument) {
231 if (has_equal)
232 optarg = has_equal;
233 else if (long_options[match].has_arg ==
234 required_argument) {
235 /*
236 * optional argument doesn't use next nargv
237 */
238 optarg = nargv[optind++];
239 }
240 }
241 if ((long_options[match].has_arg == required_argument)
242 && (optarg == NULL)) {
243 /*
244 * Missing argument; leading ':' indicates no error
245 * should be generated.
246 */
247 if (PRINT_ERROR)
248 warnx(recargstring,
249 current_argv);
250 /*
251 * XXX: GNU sets optopt to val regardless of flag
252 */
253 if (long_options[match].flag == NULL)
254 optopt = long_options[match].val;
255 else
256 optopt = 0;
257 --optind;
258 return (BADARG);
259 }
260 } else { /* unknown option */
261 if (short_too) {
262 --optind;
263 return (-1);
264 }
265 if (PRINT_ERROR)
266 warnx(illoptstring, current_argv);
267 optopt = 0;
268 return (BADCH);
269 }
270 if (idx)
271 *idx = match;
272 if (long_options[match].flag) {
273 *long_options[match].flag = long_options[match].val;
274 return (0);
275 } else
276 return (long_options[match].val);
277}
278
279/*
280 * getopt_internal --
281 * Parse argc/argv argument vector. Called by user level routines.
282 */
283static int
284getopt_internal(int nargc, char * const *nargv, const char *options,
285 const struct option *long_options, int *idx, int flags)
286{
287 char *oli; /* option letter list index */
288 int optchar, short_too;
289 static int posixly_correct = -1;
290
291 if (options == NULL)
292 return (-1);
293
294 /*
295 * XXX Some GNU programs (like cvs) set optind to 0 instead of
296 * XXX using optreset. Work around this braindamage.
297 */
298 if (optind == 0)
299 optind = optreset = 1;
300
301 /*
302 * Disable GNU extensions if POSIXLY_CORRECT is set or options
303 * string begins with a '+'.
304 */
305 if (posixly_correct == -1 || optreset)
306 posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
307 if (*options == '-')
308 flags |= FLAG_ALLARGS;
309 else if (posixly_correct || *options == '+')
310 flags &= ~FLAG_PERMUTE;
311 if (*options == '+' || *options == '-')
312 options++;
313
314 optarg = NULL;
315 if (optreset)
316 nonopt_start = nonopt_end = -1;
317start:
318 if (optreset || !*place) { /* update scanning pointer */
319 optreset = 0;
320 if (optind >= nargc) { /* end of argument vector */
321 place = EMSG;
322 if (nonopt_end != -1) {
323 /* do permutation, if we have to */
324 permute_args(nonopt_start, nonopt_end,
325 optind, nargv);
326 optind -= nonopt_end - nonopt_start;
327 }
328 else if (nonopt_start != -1) {
329 /*
330 * If we skipped non-options, set optind
331 * to the first of them.
332 */
333 optind = nonopt_start;
334 }
335 nonopt_start = nonopt_end = -1;
336 return (-1);
337 }
338 if (*(place = nargv[optind]) != '-' ||
339 (place[1] == '\0' && strchr(options, '-') == NULL)) {
340 place = EMSG; /* found non-option */
341 if (flags & FLAG_ALLARGS) {
342 /*
343 * GNU extension:
344 * return non-option as argument to option 1
345 */
346 optarg = nargv[optind++];
347 return (INORDER);
348 }
349 if (!(flags & FLAG_PERMUTE)) {
350 /*
351 * If no permutation wanted, stop parsing
352 * at first non-option.
353 */
354 return (-1);
355 }
356 /* do permutation */
357 if (nonopt_start == -1)
358 nonopt_start = optind;
359 else if (nonopt_end != -1) {
360 permute_args(nonopt_start, nonopt_end,
361 optind, nargv);
362 nonopt_start = optind -
363 (nonopt_end - nonopt_start);
364 nonopt_end = -1;
365 }
366 optind++;
367 /* process next argument */
368 goto start;
369 }
370 if (nonopt_start != -1 && nonopt_end == -1)
371 nonopt_end = optind;
372
373 /*
374 * If we have "-" do nothing, if "--" we are done.
375 */
376 if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
377 optind++;
378 place = EMSG;
379 /*
380 * We found an option (--), so if we skipped
381 * non-options, we have to permute.
382 */
383 if (nonopt_end != -1) {
384 permute_args(nonopt_start, nonopt_end,
385 optind, nargv);
386 optind -= nonopt_end - nonopt_start;
387 }
388 nonopt_start = nonopt_end = -1;
389 return (-1);
390 }
391 }
392
393 /*
394 * Check long options if:
395 * 1) we were passed some
396 * 2) the arg is not just "-"
397 * 3) either the arg starts with -- we are getopt_long_only()
398 */
399 if (long_options != NULL && place != nargv[optind] &&
400 (*place == '-' || (flags & FLAG_LONGONLY))) {
401 short_too = 0;
402 if (*place == '-')
403 place++; /* --foo long option */
404 else if (*place != ':' && strchr(options, *place) != NULL)
405 short_too = 1; /* could be short option too */
406
407 optchar = parse_long_options(nargv, options, long_options,
408 idx, short_too, flags);
409 if (optchar != -1) {
410 place = EMSG;
411 return (optchar);
412 }
413 }
414
415 if ((optchar = (int)*place++) == (int)':' ||
416 (optchar == (int)'-' && *place != '\0') ||
417 (oli = strchr(options, optchar)) == NULL) {
418 /*
419 * If the user specified "-" and '-' isn't listed in
420 * options, return -1 (non-option) as per POSIX.
421 * Otherwise, it is an unknown option character (or ':').
422 */
423 if (optchar == (int)'-' && *place == '\0')
424 return (-1);
425 if (!*place)
426 ++optind;
427 if (PRINT_ERROR)
428 warnx(illoptchar, optchar);
429 optopt = optchar;
430 return (BADCH);
431 }
432 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
433 /* -W long-option */
434 if (*place) /* no space */
435 /* NOTHING */;
436 else if (++optind >= nargc) { /* no arg */
437 place = EMSG;
438 if (PRINT_ERROR)
439 warnx(recargchar, optchar);
440 optopt = optchar;
441 return (BADARG);
442 } else /* white space */
443 place = nargv[optind];
444 optchar = parse_long_options(nargv, options, long_options,
445 idx, 0, flags);
446 place = EMSG;
447 return (optchar);
448 }
449 if (*++oli != ':') { /* doesn't take argument */
450 if (!*place)
451 ++optind;
452 } else { /* takes (optional) argument */
453 optarg = NULL;
454 if (*place) /* no white space */
455 optarg = place;
456 else if (oli[1] != ':') { /* arg not optional */
457 if (++optind >= nargc) { /* no arg */
458 place = EMSG;
459 if (PRINT_ERROR)
460 warnx(recargchar, optchar);
461 optopt = optchar;
462 return (BADARG);
463 } else
464 optarg = nargv[optind];
465 }
466 place = EMSG;
467 ++optind;
468 }
469 /* dump back option letter */
470 return (optchar);
471}
472
473/*
474 * getopt --
475 * Parse argc/argv argument vector.
476 *
477 * [eventually this will replace the BSD getopt]
478 */
479int
480getopt(int nargc, char * const *nargv, const char *options)
481{
482
483 /*
484 * We don't pass FLAG_PERMUTE to getopt_internal() since
485 * the BSD getopt(3) (unlike GNU) has never done this.
486 *
487 * Furthermore, since many privileged programs call getopt()
488 * before dropping privileges it makes sense to keep things
489 * as simple (and bug-free) as possible.
490 */
491 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
492}
493
494/*
495 * getopt_long --
496 * Parse argc/argv argument vector.
497 */
498int
499getopt_long(int nargc, char * const *nargv, const char *options,
500 const struct option *long_options, int *idx)
501{
502
503 return (getopt_internal(nargc, nargv, options, long_options, idx,
504 FLAG_PERMUTE));
505}
506
507/*
508 * getopt_long_only --
509 * Parse argc/argv argument vector.
510 */
511int
512getopt_long_only(int nargc, char * const *nargv, const char *options,
513 const struct option *long_options, int *idx)
514{
515
516 return (getopt_internal(nargc, nargv, options, long_options, idx,
517 FLAG_PERMUTE|FLAG_LONGONLY));
518}
diff --git a/src/lib/libc/stdlib/getsubopt.3 b/src/lib/libc/stdlib/getsubopt.3
new file mode 100644
index 0000000000..ef813430de
--- /dev/null
+++ b/src/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,145 @@
1.\" $OpenBSD: getsubopt.3,v 1.13 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)getsubopt.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt GETSUBOPT 3
34.Os
35.Sh NAME
36.Nm getsubopt
37.Nd get sub options from an argument
38.Sh SYNOPSIS
39.In stdlib.h
40.Vt extern char *suboptarg;
41.Ft int
42.Fn getsubopt "char **optionp" "char * const *tokens" "char **valuep"
43.Sh DESCRIPTION
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..ea264b57c8
--- /dev/null
+++ b/src/lib/libc/stdlib/hcreate.3
@@ -0,0 +1,239 @@
1.\" $OpenBSD: hcreate.3,v 1.6 2010/07/28 09:00:20 ray Exp $
2.\" $NetBSD: hcreate.3,v 1.8 2010/05/01 06:18:03 jruoho Exp $
3.\"
4.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" This code is derived from software contributed to The NetBSD Foundation
8.\" by Klaus Klein.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29.\" POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd $Mdocdate: July 28 2010 $
32.Dt HCREATE 3
33.Os
34.Sh NAME
35.Nm hcreate ,
36.Nm hdestroy ,
37.Nm hsearch
38.Nd manage hash search table
39.Sh SYNOPSIS
40.In search.h
41.Ft int
42.Fn hcreate "size_t nel"
43.Ft void
44.Fn hdestroy "void"
45.Ft ENTRY *
46.Fn hsearch "ENTRY item" "ACTION action"
47.Sh DESCRIPTION
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.Vt ENTRY ,
88defined in the
89.In search.h
90header.
91This is a structure type that contains two pointers:
92.Pp
93.Bl -tag -compact -offset indent -width "void *data "
94.It Fa char *key
95comparison key
96.It Fa void *data
97pointer to data associated with
98.Fa key
99.El
100.Pp
101The key comparison function used by
102.Fn hsearch
103is
104.Xr strcmp 3 .
105.Pp
106The
107.Fa action
108argument is of type
109.Vt ACTION ,
110an enumeration type which defines the following values:
111.Bl -tag -offset indent -width ENTERXX
112.It Dv ENTER
113Insert
114.Fa item
115into the hash table.
116If an existing item with the same key is found, it is not replaced.
117Note that the
118.Fa key
119and
120.Fa data
121elements of
122.Fa item
123are used directly by the new table entry.
124The storage for the
125key must not be modified during the lifetime of the hash table.
126.It Dv FIND
127Search the hash table without inserting
128.Fa item .
129.El
130.Pp
131Note that the comparison
132.Fa key
133must be allocated using
134.Xr malloc 3
135or
136.Xr calloc 3
137if action is
138.Dv ENTER
139and
140.Fn hdestroy
141will be called.
142This is because
143.Fn hdestroy
144will call
145.Xr free 3
146for each comparison
147.Fa key
148(but not
149.Fa data ) .
150Typically the comparison
151.Fa key
152is allocated by using
153.Xr strdup 3 .
154.Sh RETURN VALUES
155If successful, the
156.Fn hcreate
157function returns a non-zero value.
158Otherwise, a value of 0 is returned and
159.Va errno
160is set to indicate the error.
161.Pp
162The
163.Fn hdestroy
164functions
165returns no value.
166.Pp
167If successful, the
168.Fn hsearch
169function returns a pointer to a hash table entry matching
170the provided key.
171If the action is
172.Dv FIND
173and the item was not found, or if the action is
174.Dv ENTER
175and the insertion failed,
176.Dv NULL
177is returned and
178.Va errno
179is set to indicate the error.
180If the action is
181.Dv ENTER
182and an entry already existed in the table matching the given
183key, the existing entry is returned and is not replaced.
184.Sh ERRORS
185The
186.Fn hcreate
187and
188.Fn hsearch
189functions will fail if:
190.Bl -tag -width Er
191.It Bq Er ENOMEM
192Insufficient memory is available.
193.El
194.Sh SEE ALSO
195.Xr bsearch 3 ,
196.Xr lsearch 3 ,
197.Xr malloc 3 ,
198.Xr strcmp 3
199.Sh STANDARDS
200The
201.Fn hcreate ,
202.Fn hdestroy
203and
204.Fn hsearch
205functions conform to
206.St -xpg4.2 .
207.Sh HISTORY
208The
209.Fn hcreate ,
210.Fn hdestroy
211and
212.Fn hsearch
213functions first appeared in
214.At V .
215.Sh CAVEATS
216At least the following limitations can be mentioned:
217.Bl -bullet
218.It
219The interface permits the use of only one hash table at a time.
220.It
221Individual hash table entries can be added, but not deleted.
222.It
223The standard is indecipherable about the
224internal memory usage of the functions,
225mentioning only that
226.Do
227.Fn hcreate
228and
229.Fn hsearch
230functions may use
231.Fn malloc
232to allocate space
233.Dc .
234This limits the portability of the functions,
235given that other implementations may not
236.Xr free 3
237the buffer pointed by
238.Fa key .
239.El
diff --git a/src/lib/libc/stdlib/hcreate.c b/src/lib/libc/stdlib/hcreate.c
new file mode 100644
index 0000000000..094f32c173
--- /dev/null
+++ b/src/lib/libc/stdlib/hcreate.c
@@ -0,0 +1,191 @@
1/* $OpenBSD: hcreate.c,v 1.4 2007/09/02 15:19:17 deraadt Exp $ */
2/* $NetBSD: hcreate.c,v 1.5 2004/04/23 02:48:12 simonb Exp $ */
3
4/*
5 * Copyright (c) 2001 Christopher G. Demetriou
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed for the
19 * NetBSD Project. See http://www.NetBSD.org/ for
20 * information about NetBSD.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
36 */
37
38/*
39 * hcreate() / hsearch() / hdestroy()
40 *
41 * SysV/XPG4 hash table functions.
42 *
43 * Implementation done based on NetBSD manual page and Solaris manual page,
44 * plus my own personal experience about how they're supposed to work.
45 *
46 * I tried to look at Knuth (as cited by the Solaris manual page), but
47 * nobody had a copy in the office, so...
48 */
49
50#include "namespace.h"
51#include <assert.h>
52#include <errno.h>
53#include <inttypes.h>
54#include <search.h>
55#include <stdlib.h>
56#include <string.h>
57#include <sys/queue.h>
58
59#ifndef _DIAGASSERT
60#define _DIAGASSERT(x)
61#endif
62
63/*
64 * DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit
65 * ptr machine) without adjusting MAX_BUCKETS_LG2 below.
66 */
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
new file mode 100644
index 0000000000..ad3fffbcd9
--- /dev/null
+++ b/src/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,173 @@
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ronnie Kon at Mindcraft Inc., Kevin Lew and Elmer Yglesias.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. 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 <sys/types.h>
34#include <errno.h>
35#include <stdlib.h>
36
37/*
38 * Swap two areas of size number of bytes. Although qsort(3) permits random
39 * blocks of memory to be sorted, sorting pointers is almost certainly the
40 * common case (and, were it not, could easily be made so). Regardless, it
41 * isn't worth optimizing; the SWAP's get sped up by the cache, and pointer
42 * arithmetic gets lost in the time required for comparison function calls.
43 */
44#define SWAP(a, b, count, size, tmp) { \
45 count = size; \
46 do { \
47 tmp = *a; \
48 *a++ = *b; \
49 *b++ = tmp; \
50 } while (--count); \
51}
52
53/* Copy one block of size size to another. */
54#define COPY(a, b, count, size, tmp1, tmp2) { \
55 count = size; \
56 tmp1 = a; \
57 tmp2 = b; \
58 do { \
59 *tmp1++ = *tmp2++; \
60 } while (--count); \
61}
62
63/*
64 * Build the list into a heap, where a heap is defined such that for
65 * the records K1 ... KN, Kj/2 >= Kj for 1 <= j/2 <= j <= N.
66 *
67 * There are two cases. If j == nmemb, select largest of Ki and Kj. If
68 * j < nmemb, select largest of Ki, Kj and Kj+1.
69 */
70#define CREATE(initval, nmemb, par_i, child_i, par, child, size, count, tmp) { \
71 for (par_i = initval; (child_i = par_i * 2) <= nmemb; \
72 par_i = child_i) { \
73 child = base + child_i * size; \
74 if (child_i < nmemb && compar(child, child + size) < 0) { \
75 child += size; \
76 ++child_i; \
77 } \
78 par = base + par_i * size; \
79 if (compar(child, par) <= 0) \
80 break; \
81 SWAP(par, child, count, size, tmp); \
82 } \
83}
84
85/*
86 * Select the top of the heap and 'heapify'. Since by far the most expensive
87 * action is the call to the compar function, a considerable optimization
88 * in the average case can be achieved due to the fact that k, the displaced
89 * element, is usually quite small, so it would be preferable to first
90 * heapify, always maintaining the invariant that the larger child is copied
91 * over its parent's record.
92 *
93 * Then, starting from the *bottom* of the heap, finding k's correct place,
94 * again maintaining the invariant. As a result of the invariant no element
95 * is 'lost' when k is assigned its correct place in the heap.
96 *
97 * The time savings from this optimization are on the order of 15-20% for the
98 * average case. See Knuth, Vol. 3, page 158, problem 18.
99 *
100 * XXX Don't break the #define SELECT line, below. Reiser cpp gets upset.
101 */
102#define SELECT(par_i, child_i, nmemb, par, child, size, k, count, tmp1, tmp2) { \
103 for (par_i = 1; (child_i = par_i * 2) <= nmemb; par_i = child_i) { \
104 child = base + child_i * size; \
105 if (child_i < nmemb && compar(child, child + size) < 0) { \
106 child += size; \
107 ++child_i; \
108 } \
109 par = base + par_i * size; \
110 COPY(par, child, count, size, tmp1, tmp2); \
111 } \
112 for (;;) { \
113 child_i = par_i; \
114 par_i = child_i / 2; \
115 child = base + child_i * size; \
116 par = base + par_i * size; \
117 if (child_i == 1 || compar(k, par) < 0) { \
118 COPY(child, k, count, size, tmp1, tmp2); \
119 break; \
120 } \
121 COPY(child, par, count, size, tmp1, tmp2); \
122 } \
123}
124
125/*
126 * Heapsort -- Knuth, Vol. 3, page 145. Runs in O (N lg N), both average
127 * and worst. While heapsort is faster than the worst case of quicksort,
128 * the BSD quicksort does median selection so that the chance of finding
129 * a data set that will trigger the worst case is nonexistent. Heapsort's
130 * only advantage over quicksort is that it requires little additional memory.
131 */
132int
133heapsort(void *vbase, size_t nmemb, size_t size,
134 int (*compar)(const void *, const void *))
135{
136 size_t cnt, i, j, l;
137 char tmp, *tmp1, *tmp2;
138 char *base, *k, *p, *t;
139
140 if (nmemb <= 1)
141 return (0);
142
143 if (!size) {
144 errno = EINVAL;
145 return (-1);
146 }
147
148 if ((k = malloc(size)) == NULL)
149 return (-1);
150
151 /*
152 * Items are numbered from 1 to nmemb, so offset from size bytes
153 * below the starting address.
154 */
155 base = (char *)vbase - size;
156
157 for (l = nmemb / 2 + 1; --l;)
158 CREATE(l, nmemb, i, j, t, p, size, cnt, tmp);
159
160 /*
161 * For each element of the heap, save the largest element into its
162 * final slot, save the displaced element (k), then recreate the
163 * heap.
164 */
165 while (nmemb > 1) {
166 COPY(k, base + nmemb * size, cnt, size, tmp1, tmp2);
167 COPY(base + nmemb * size, base + size, cnt, size, tmp1, tmp2);
168 --nmemb;
169 SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
170 }
171 free(k);
172 return (0);
173}
diff --git a/src/lib/libc/stdlib/imaxabs.3 b/src/lib/libc/stdlib/imaxabs.3
new file mode 100644
index 0000000000..6c4793477e
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxabs.3
@@ -0,0 +1,65 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" 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. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: imaxabs.3,v 1.6 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt IMAXABS 3
36.Os
37.Sh NAME
38.Nm imaxabs
39.Nd integer absolute value function
40.Sh SYNOPSIS
41.In inttypes.h
42.Ft intmax_t
43.Fn imaxabs "intmax_t j"
44.Sh DESCRIPTION
45The
46.Fn imaxabs
47function computes the absolute value of the intmax_t variable
48.Fa j .
49.Sh RETURN VALUES
50The
51.Fn imaxabs
52function returns the absolute value.
53.Sh SEE ALSO
54.Xr abs 3 ,
55.Xr cabs 3 ,
56.Xr floor 3 ,
57.Xr hypot 3 ,
58.Xr labs 3
59.Sh STANDARDS
60The
61.Fn imaxabs
62function conforms to
63.St -ansiC-99 .
64.Sh BUGS
65The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/imaxabs.c b/src/lib/libc/stdlib/imaxabs.c
new file mode 100644
index 0000000000..b7e910eefd
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxabs.c
@@ -0,0 +1,38 @@
1/* $OpenBSD: imaxabs.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <inttypes.h>
33
34intmax_t
35imaxabs(intmax_t j)
36{
37 return (j < 0 ? -j : j);
38}
diff --git a/src/lib/libc/stdlib/imaxdiv.3 b/src/lib/libc/stdlib/imaxdiv.3
new file mode 100644
index 0000000000..40ac0bc236
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxdiv.3
@@ -0,0 +1,66 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: imaxdiv.3,v 1.5 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt IMAXDIV 3
36.Os
37.Sh NAME
38.Nm imaxdiv
39.Nd return quotient and remainder from division
40.Sh SYNOPSIS
41.In inttypes.h
42.Ft imaxdiv_t
43.Fn imaxdiv "intmax_t num" "intmax_t denom"
44.Sh DESCRIPTION
45The
46.Fn imaxdiv
47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li imaxdiv_t
51that contains two
52.Li intmax_t
53members named
54.Fa quot
55and
56.Fa rem .
57.Sh SEE ALSO
58.Xr div 3 ,
59.Xr ldiv 3 ,
60.Xr lldiv 3 ,
61.Xr qdiv 3
62.Sh STANDARDS
63The
64.Fn imaxdiv
65function conforms to
66.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/imaxdiv.c b/src/lib/libc/stdlib/imaxdiv.c
new file mode 100644
index 0000000000..0515a94b96
--- /dev/null
+++ b/src/lib/libc/stdlib/imaxdiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: imaxdiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2/*
3 * Copyright (c) 1990 Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <inttypes.h> /* imaxdiv_t */
35
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..64da36a898
--- /dev/null
+++ b/src/lib/libc/stdlib/insque.3
@@ -0,0 +1,106 @@
1.\" $OpenBSD: insque.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
2.\" Copyright (c) 1993 John Brezak
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may be used to endorse or promote products
14.\" derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"
29.Dd $Mdocdate: June 5 2013 $
30.Dt INSQUE 3
31.Os
32.Sh NAME
33.Nm insque ,
34.Nm remque
35.Nd insert/remove element from a queue
36.Sh SYNOPSIS
37.In search.h
38.Ft void
39.Fn insque "void *elem" "void *pred"
40.Ft void
41.Fn remque "void *elem"
42.Sh DESCRIPTION
43.Bf -symbolic
44These interfaces have been superseded 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
new file mode 100644
index 0000000000..cb8c592750
--- /dev/null
+++ b/src/lib/libc/stdlib/jrand48.c
@@ -0,0 +1,22 @@
1/* $OpenBSD: jrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17long
18jrand48(unsigned short xseed[3])
19{
20 __dorand48(xseed);
21 return ((long) xseed[2] << 16) + (long) xseed[1];
22}
diff --git a/src/lib/libc/stdlib/l64a.c b/src/lib/libc/stdlib/l64a.c
new file mode 100644
index 0000000000..4f33df37b2
--- /dev/null
+++ b/src/lib/libc/stdlib/l64a.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: l64a.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Written by J.T. Conklin <jtc@netbsd.org>.
4 * Public domain.
5 */
6
7#include <errno.h>
8#include <stdlib.h>
9
10char *
11l64a(long value)
12{
13 static char buf[8];
14 char *s = buf;
15 int digit;
16 int i;
17
18 if (value < 0) {
19 errno = EINVAL;
20 return(NULL);
21 }
22
23 for (i = 0; value != 0 && i < 6; i++) {
24 digit = value & 0x3f;
25
26 if (digit < 2)
27 *s = digit + '.';
28 else if (digit < 12)
29 *s = digit + '0' - 2;
30 else if (digit < 38)
31 *s = digit + 'A' - 12;
32 else
33 *s = digit + 'a' - 38;
34
35 value >>= 6;
36 s++;
37 }
38
39 *s = '\0';
40
41 return(buf);
42}
diff --git a/src/lib/libc/stdlib/labs.3 b/src/lib/libc/stdlib/labs.3
new file mode 100644
index 0000000000..a38c64b1af
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.3
@@ -0,0 +1,69 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: labs.3,v 1.12 2014/01/19 05:21:12 schwarze Exp $
33.\"
34.Dd $Mdocdate: January 19 2014 $
35.Dt LABS 3
36.Os
37.Sh NAME
38.Nm labs ,
39.Nm llabs
40.Nd return the absolute value of a long integer
41.Sh SYNOPSIS
42.In stdlib.h
43.Ft long
44.Fn labs "long i"
45.Ft long long
46.Fn llabs "long long j"
47.Sh DESCRIPTION
48The
49.Fn labs
50function returns the absolute value of the long integer
51.Fa i .
52The
53.Fn llabs
54function returns the absolute value of the long long integer
55.Fa j .
56.Sh SEE ALSO
57.Xr abs 3 ,
58.Xr cabs 3 ,
59.Xr floor 3 ,
60.Xr imaxabs 3
61.Sh STANDARDS
62The
63.Fn labs
64and
65.Fn llabs
66functions conform to
67.St -ansiC-99 .
68.Sh BUGS
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
new file mode 100644
index 0000000000..ca60b9aba2
--- /dev/null
+++ b/src/lib/libc/stdlib/labs.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: labs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33long
34labs(long j)
35{
36 return(j < 0 ? -j : j);
37}
diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c
new file mode 100644
index 0000000000..2cf5c271ba
--- /dev/null
+++ b/src/lib/libc/stdlib/lcong48.c
@@ -0,0 +1,31 @@
1/* $OpenBSD: lcong48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18extern unsigned short __rand48_mult[3];
19extern unsigned short __rand48_add;
20
21void
22lcong48(unsigned short p[7])
23{
24 __rand48_seed[0] = p[0];
25 __rand48_seed[1] = p[1];
26 __rand48_seed[2] = p[2];
27 __rand48_mult[0] = p[3];
28 __rand48_mult[1] = p[4];
29 __rand48_mult[2] = p[5];
30 __rand48_add = p[6];
31}
diff --git a/src/lib/libc/stdlib/ldiv.3 b/src/lib/libc/stdlib/ldiv.3
new file mode 100644
index 0000000000..a8835ab6ac
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,72 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: ldiv.3,v 1.12 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt LDIV 3
36.Os
37.Sh NAME
38.Nm ldiv
39.Nd return quotient and remainder from division
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft ldiv_t
43.Fn ldiv "long num" "long denom"
44.Sh DESCRIPTION
45The
46.Fn ldiv
47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li ldiv_t
51that contains two
52.Li long integer
53members named
54.Fa quot
55and
56.Fa rem .
57.Sh SEE ALSO
58.Xr div 3 ,
59.Xr imaxdiv 3 ,
60.Xr lldiv 3 ,
61.Xr qdiv 3
62.Sh STANDARDS
63The
64.Fn ldiv
65function conforms to
66.St -ansiC .
67.Sh HISTORY
68An
69.Fn ldiv
70function with similar functionality, but a different calling convention,
71first appeared in
72.At v4 .
diff --git a/src/lib/libc/stdlib/ldiv.c b/src/lib/libc/stdlib/ldiv.c
new file mode 100644
index 0000000000..775065f525
--- /dev/null
+++ b/src/lib/libc/stdlib/ldiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: ldiv.c,v 1.5 2005/08/08 08:05:36 espie 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> /* ldiv_t */
35
36ldiv_t
37ldiv(long num, long denom)
38{
39 ldiv_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/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/lldiv.3 b/src/lib/libc/stdlib/lldiv.3
new file mode 100644
index 0000000000..9181f8b7c5
--- /dev/null
+++ b/src/lib/libc/stdlib/lldiv.3
@@ -0,0 +1,66 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: lldiv.3,v 1.4 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt LLDIV 3
36.Os
37.Sh NAME
38.Nm lldiv
39.Nd return quotient and remainder from division
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft lldiv_t
43.Fn lldiv "long long num" "long long denom"
44.Sh DESCRIPTION
45The
46.Fn lldiv
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 .
57.Sh SEE ALSO
58.Xr div 3 ,
59.Xr imaxdiv 3 ,
60.Xr ldiv 3 ,
61.Xr qdiv 3
62.Sh STANDARDS
63The
64.Fn lldiv
65function conforms to
66.St -ansiC-99 .
diff --git a/src/lib/libc/stdlib/lldiv.c b/src/lib/libc/stdlib/lldiv.c
new file mode 100644
index 0000000000..e8d6c978b3
--- /dev/null
+++ b/src/lib/libc/stdlib/lldiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: lldiv.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2/*
3 * Copyright (c) 1990 Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <stdlib.h> /* lldiv_t */
35
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
new file mode 100644
index 0000000000..21beb858ca
--- /dev/null
+++ b/src/lib/libc/stdlib/lrand48.c
@@ -0,0 +1,24 @@
1/* $OpenBSD: lrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18
19long
20lrand48(void)
21{
22 __dorand48(__rand48_seed);
23 return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1);
24}
diff --git a/src/lib/libc/stdlib/lsearch.3 b/src/lib/libc/stdlib/lsearch.3
new file mode 100644
index 0000000000..c5a55980e1
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.3
@@ -0,0 +1,108 @@
1.\" $OpenBSD: lsearch.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1989, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)lsearch.3 8.1 (Berkeley) 6/4/93
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt LSEARCH 3
34.Os
35.Sh NAME
36.Nm lsearch ,
37.Nm lfind
38.Nd linear searching routines
39.Sh SYNOPSIS
40.In search.h
41.Ft char *
42.Fn lsearch "const void *key" "const void *base" "size_t *nelp" \
43 "size_t width" "int (*compar)(const void *, const void *)"
44.Ft char *
45.Fn lfind "const void *key" "const void *base" "size_t *nelp" \
46 "size_t width" "int (*compar)(const void *, const void *)"
47.Sh DESCRIPTION
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..a01d80e008
--- /dev/null
+++ b/src/lib/libc/stdlib/lsearch.c
@@ -0,0 +1,84 @@
1/* $OpenBSD: lsearch.c,v 1.4 2009/10/27 23:59:59 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Roger L. Snyder.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/types.h>
36#include <string.h>
37#include <search.h>
38
39typedef int (*cmp_fn_t)(const void *, const void *);
40static void *linear_base(const void *, const void *, size_t *, size_t,
41 cmp_fn_t, int);
42
43void *
44lsearch(const void *key, const void *base, size_t *nelp, size_t width,
45 cmp_fn_t compar)
46{
47
48 return(linear_base(key, base, nelp, width, compar, 1));
49}
50
51void *
52lfind(const void *key, const void *base, size_t *nelp, size_t width,
53 cmp_fn_t compar)
54{
55 return(linear_base(key, base, nelp, width, compar, 0));
56}
57
58static void *
59linear_base(const void *key, const void *base, size_t *nelp, size_t width,
60 cmp_fn_t compar, int add_flag)
61{
62 const char *element, *end;
63
64 end = (const char *)base + *nelp * width;
65 for (element = base; element < end; element += width)
66 if (!compar(key, element)) /* key found */
67 return((void *)element);
68
69 if (!add_flag) /* key not found */
70 return(NULL);
71
72 /*
73 * The UNIX System User's Manual, 1986 edition claims that
74 * a NULL pointer is returned by lsearch with errno set
75 * appropriately, if there is not enough room in the table
76 * to add a new item. This can't be done as none of these
77 * routines have any method of determining the size of the
78 * table. This comment isn't in the 1986-87 System V
79 * manual.
80 */
81 ++*nelp;
82 memcpy((void *)end, key, width);
83 return((void *)end);
84}
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
new file mode 100644
index 0000000000..414f0a9770
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.3
@@ -0,0 +1,484 @@
1.\"
2.\" Copyright (c) 1980, 1991, 1993
3.\" The Regents of the University of California. All rights reserved.
4.\"
5.\" This code is derived from software contributed to Berkeley by
6.\" the American National Standards Committee X3, on Information
7.\" Processing Systems.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. Neither the name of the University nor the names of its contributors
18.\" may be used to endorse or promote products derived from this software
19.\" without specific prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.\" $OpenBSD: malloc.3,v 1.73 2013/07/18 10:14:49 schwarze Exp $
34.\"
35.Dd $Mdocdate: July 18 2013 $
36.Dt MALLOC 3
37.Os
38.Sh NAME
39.Nm malloc ,
40.Nm calloc ,
41.Nm realloc ,
42.Nm free ,
43.Nm cfree
44.Nd memory allocation and deallocation
45.Sh SYNOPSIS
46.In stdlib.h
47.Ft void *
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 ;
59.Sh DESCRIPTION
60The
61.Fn malloc
62function allocates uninitialized space for an object whose
63size is specified by
64.Fa size .
65The
66.Fn malloc
67function maintains multiple lists of free blocks according to size, allocating
68space from the appropriate list.
69.Pp
70The allocated space is
71suitably aligned (after possible pointer
72coercion) for storage of any type of object.
73If the space is of
74.Em pagesize
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.Sh MALLOC_OPTIONS
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 internal
219inconsistencies or incorrect usage.
220This is the default and a very handy debugging aid,
221since the core file represents the time of failure,
222rather than when the bogus pointer was used.
223.It Cm D
224.Dq Dump .
225.Fn malloc
226will dump statistics to the file
227.Pa ./malloc.out ,
228if it already exists,
229at exit.
230This option requires the library to have been compiled with -DMALLOC_STATS in
231order to have any effect.
232.It Cm F
233.Dq Freeguard .
234Enable use after free detection.
235Unused pages on the freelist are read and write protected to
236cause a segmentation fault upon access.
237This will also switch off the delayed freeing of chunks,
238reducing random behaviour but detecting double
239.Fn free
240calls as early as possible.
241This option is intended for debugging rather than improved security
242(use the
243.Cm U
244option for security).
245.It Cm G
246.Dq Guard .
247Enable guard pages.
248Each page size or larger allocation is followed by a guard page that will
249cause a segmentation fault upon any access.
250.It Cm H
251.Dq Hint .
252Pass a hint to the kernel about pages we don't use.
253If the machine is paging a lot this may help a bit.
254.It Cm J
255.Dq Junk .
256Fill some junk into the area allocated.
257Currently junk is bytes of 0xd0 when allocating; this is pronounced
258.Dq Duh .
259\&:-)
260Freed chunks are filled with 0xdf.
261.It Cm P
262.Dq Move allocations within a page.
263Allocations larger than half a page but smaller than a page
264are aligned to the end of a page to catch buffer overruns in more
265cases.
266This is the default.
267.It Cm R
268.Dq realloc .
269Always reallocate when
270.Fn realloc
271is called, even if the initial allocation was big enough.
272This can substantially aid in compacting memory.
273.\".Pp
274.\".It Cm U
275.\".Dq utrace .
276.\"Generate entries for
277.\".Xr ktrace 1
278.\"for all operations.
279.\"Consult the source for this one.
280.It Cm S
281Enable all options suitable for security auditing.
282.It Cm U
283.Dq Free unmap .
284Enable use after free protection for larger allocations.
285Unused pages on the freelist are read and write protected to
286cause a segmentation fault upon access.
287.It Cm X
288.Dq xmalloc .
289Rather than return failure,
290.Xr abort 3
291the program with a diagnostic message on stderr.
292It is the intention that this option be set at compile time by
293including in the source:
294.Bd -literal -offset indent
295extern char *malloc_options;
296malloc_options = "X";
297.Ed
298.Pp
299Note that this will cause code that is supposed to handle
300out-of-memory conditions gracefully to abort instead.
301.It Cm Z
302.Dq Zero .
303Fill some junk into the area allocated (see
304.Cm J ) ,
305except for the exact length the user asked for, which is zeroed.
306.It Cm <
307.Dq Half the cache size .
308Decrease the size of the free page cache by a factor of two.
309.It Cm >
310.Dq Double the cache size .
311Increase the size of the free page cache by a factor of two.
312.El
313.Pp
314So to set a systemwide reduction of the cache to a quarter of the
315default size and use guard pages:
316.Dl # ln -s 'G\*(Lt\*(Lt' /etc/malloc.conf
317.Pp
318The flags are mostly for testing and debugging.
319If a program changes behavior if any of these options (except
320.Cm X )
321are used,
322it is buggy.
323.Pp
324The default number of free pages cached is 64.
325.Sh RETURN VALUES
326The
327.Fn malloc
328and
329.Fn calloc
330functions return a pointer to the allocated space if successful; otherwise,
331a null pointer is returned and
332.Va errno
333is set to
334.Er ENOMEM .
335.Pp
336The
337.Fn free
338and
339.Fn cfree
340functions return no value.
341.Pp
342The
343.Fn realloc
344function returns a pointer to the (possibly moved) allocated space
345if successful; otherwise, a null pointer is returned and
346.Va errno
347is set to
348.Er ENOMEM .
349.Sh ENVIRONMENT
350.Bl -tag -width Ev
351.It Ev MALLOC_OPTIONS
352See above.
353.El
354.Sh FILES
355.Bl -tag -width "/etc/malloc.conf"
356.It Pa /etc/malloc.conf
357symbolic link to filename containing option flags
358.El
359.Sh DIAGNOSTICS
360If
361.Fn malloc ,
362.Fn calloc ,
363.Fn realloc ,
364or
365.Fn free
366detect an error condition,
367a message will be printed to file descriptor
3682 (not using stdio).
369Errors will result in the process being aborted,
370unless the
371.Cm a
372option has been specified.
373.Pp
374Here is a brief description of the error messages and what they mean:
375.Bl -tag -width Ds
376.It Dq out of memory
377If the
378.Cm X
379option is specified it is an error for
380.Fn malloc ,
381.Fn calloc ,
382or
383.Fn realloc
384to return
385.Dv NULL .
386.It Dq malloc init mmap failed
387This is a rather weird condition that is most likely to indicate a
388seriously overloaded system or a ulimit restriction.
389.It Dq bogus pointer (double free?)
390An attempt to
391.Fn free
392or
393.Fn realloc
394an unallocated pointer was made.
395.It Dq chunk is already free
396There was an attempt to free a chunk that had already been freed.
397.It Dq modified chunk-pointer
398The pointer passed to
399.Fn free
400or
401.Fn realloc
402has been modified.
403.It Dq recursive call
404An attempt was made to call recursively into these functions, i.e., from a
405signal handler.
406This behavior is not supported.
407In particular, signal handlers should
408.Em not
409use any of the
410.Fn malloc
411functions nor utilize any other functions which may call
412.Fn malloc
413(e.g.,
414.Xr stdio 3
415routines).
416.It Dq unknown char in MALLOC_OPTIONS
417We found something we didn't understand.
418.It Dq malloc cache overflow/underflow
419The internal malloc page cache has been corrupted.
420.It Dq malloc free slot lost
421The internal malloc page cache has been corrupted.
422.It Dq guard size
423An inconsistent guard size was detected.
424.It any other error
425.Fn malloc
426detected an internal error;
427consult sources and/or wizards.
428.El
429.Sh SEE ALSO
430.Xr brk 2 ,
431.Xr mmap 2 ,
432.Xr munmap 2 ,
433.Xr alloca 3 ,
434.Xr getpagesize 3 ,
435.Xr posix_memalign 3
436.Sh STANDARDS
437The
438.Fn malloc
439function conforms to
440.St -ansiC .
441.Sh HISTORY
442A
443.Fn free
444internal kernel function and a predecessor to
445.Fn malloc ,
446.Fn alloc ,
447first appeared in
448.At v1 .
449C library functions
450.Fn alloc
451and
452.Fn free
453appeared in
454.At v6 .
455The functions
456.Fn malloc ,
457.Fn calloc ,
458and
459.Fn realloc
460first appeared in
461.At v7 .
462.Pp
463A new implementation by Chris Kingsley was introduced in
464.Bx 4.2 ,
465followed by a complete rewrite by Poul-Henning Kamp which appeared in
466.Fx 2.2
467and was included in
468.Ox 2.0 .
469These implementations were all
470.Xr sbrk 2
471based.
472In
473.Ox 3.8 ,
474Thierry Deval rewrote
475.Nm
476to use the
477.Xr mmap 2
478system call,
479making the page addresses returned by
480.Nm
481random.
482A rewrite by Otto Moerbeek introducing a new central data structure and more
483randomization appeared in
484.Ox 4.4 .
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000000..446a1ca254
--- /dev/null
+++ b/src/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1820 @@
1/* $OpenBSD: malloc.c,v 1.152 2014/04/03 16:18:11 schwarze Exp $ */
2/*
3 * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
5 * Copyright (c) 2008 Damien Miller <djm@openbsd.org>
6 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * If we meet some day, and you think this stuff is worth it, you
23 * can buy me a beer in return. Poul-Henning Kamp
24 */
25
26/* #define MALLOC_STATS */
27
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/mman.h>
32#include <sys/uio.h>
33#include <errno.h>
34#include <stdint.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdio.h>
38#include <unistd.h>
39
40#ifdef MALLOC_STATS
41#include <sys/tree.h>
42#include <fcntl.h>
43#endif
44
45#include "thread_private.h"
46
47#if defined(__sparc__) && !defined(__sparcv9__)
48#define MALLOC_PAGESHIFT (13U)
49#elif defined(__mips64__)
50#define MALLOC_PAGESHIFT (14U)
51#else
52#define MALLOC_PAGESHIFT (PAGE_SHIFT)
53#endif
54
55#define MALLOC_MINSHIFT 4
56#define MALLOC_MAXSHIFT (MALLOC_PAGESHIFT - 1)
57#define MALLOC_PAGESIZE (1UL << MALLOC_PAGESHIFT)
58#define MALLOC_MINSIZE (1UL << MALLOC_MINSHIFT)
59#define MALLOC_PAGEMASK (MALLOC_PAGESIZE - 1)
60#define MASK_POINTER(p) ((void *)(((uintptr_t)(p)) & ~MALLOC_PAGEMASK))
61
62#define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT)
63#define MALLOC_MAXCACHE 256
64#define MALLOC_DELAYED_CHUNKS 15 /* max of getrnibble() */
65#define MALLOC_INITIAL_REGIONS 512
66#define MALLOC_DEFAULT_CACHE 64
67
68/*
69 * When the P option is active, we move allocations between half a page
70 * and a whole page towards the end, subject to alignment constraints.
71 * This is the extra headroom we allow. Set to zero to be the most
72 * strict.
73 */
74#define MALLOC_LEEWAY 0
75
76#define PAGEROUND(x) (((x) + (MALLOC_PAGEMASK)) & ~MALLOC_PAGEMASK)
77
78/*
79 * What to use for Junk. This is the byte value we use to fill with
80 * when the 'J' option is enabled. Use SOME_JUNK right after alloc,
81 * and SOME_FREEJUNK right before free.
82 */
83#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
84#define SOME_FREEJUNK 0xdf
85
86#define MMAP(sz) mmap(NULL, (size_t)(sz), PROT_READ | PROT_WRITE, \
87 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
88
89#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
90 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
91
92#define MQUERY(a, sz) mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
93 MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, (off_t)0)
94
95struct region_info {
96 void *p; /* page; low bits used to mark chunks */
97 uintptr_t size; /* size for pages, or chunk_info pointer */
98#ifdef MALLOC_STATS
99 void *f; /* where allocated from */
100#endif
101};
102
103LIST_HEAD(chunk_head, chunk_info);
104
105struct dir_info {
106 u_int32_t canary1;
107 struct region_info *r; /* region slots */
108 size_t regions_total; /* number of region slots */
109 size_t regions_free; /* number of free slots */
110 /* lists of free chunk info structs */
111 struct chunk_head chunk_info_list[MALLOC_MAXSHIFT + 1];
112 /* lists of chunks with free slots */
113 struct chunk_head chunk_dir[MALLOC_MAXSHIFT + 1];
114 size_t free_regions_size; /* free pages cached */
115 /* free pages cache */
116 struct region_info free_regions[MALLOC_MAXCACHE];
117 /* delayed free chunk slots */
118 void *delayed_chunks[MALLOC_DELAYED_CHUNKS + 1];
119 u_short chunk_start;
120#ifdef MALLOC_STATS
121 size_t inserts;
122 size_t insert_collisions;
123 size_t finds;
124 size_t find_collisions;
125 size_t deletes;
126 size_t delete_moves;
127 size_t cheap_realloc_tries;
128 size_t cheap_reallocs;
129#define STATS_INC(x) ((x)++)
130#define STATS_ZERO(x) ((x) = 0)
131#define STATS_SETF(x,y) ((x)->f = (y))
132#else
133#define STATS_INC(x) /* nothing */
134#define STATS_ZERO(x) /* nothing */
135#define STATS_SETF(x,y) /* nothing */
136#endif /* MALLOC_STATS */
137 u_int32_t canary2;
138};
139#define DIR_INFO_RSZ ((sizeof(struct dir_info) + MALLOC_PAGEMASK) & \
140 ~MALLOC_PAGEMASK)
141
142/*
143 * This structure describes a page worth of chunks.
144 *
145 * How many bits per u_short in the bitmap
146 */
147#define MALLOC_BITS (NBBY * sizeof(u_short))
148struct chunk_info {
149 LIST_ENTRY(chunk_info) entries;
150 void *page; /* pointer to the page */
151 u_int32_t canary;
152 u_short size; /* size of this page's chunks */
153 u_short shift; /* how far to shift for this size */
154 u_short free; /* how many free chunks */
155 u_short total; /* how many chunk */
156 /* which chunks are free */
157 u_short bits[1];
158};
159
160struct malloc_readonly {
161 struct dir_info *g_pool; /* Main bookkeeping information */
162 int malloc_abort; /* abort() on error */
163 int malloc_freenow; /* Free quickly - disable chunk rnd */
164 int malloc_freeunmap; /* mprotect free pages PROT_NONE? */
165 int malloc_hint; /* call madvice on free pages? */
166 int malloc_junk; /* junk fill? */
167 int malloc_move; /* move allocations to end of page? */
168 int malloc_realloc; /* always realloc? */
169 int malloc_xmalloc; /* xmalloc behaviour? */
170 int malloc_zero; /* zero fill? */
171 size_t malloc_guard; /* use guard pages after allocations? */
172 u_int malloc_cache; /* free pages we cache */
173#ifdef MALLOC_STATS
174 int malloc_stats; /* dump statistics at end */
175#endif
176 u_int32_t malloc_canary; /* Matched against ones in g_pool */
177};
178
179/* This object is mapped PROT_READ after initialisation to prevent tampering */
180static union {
181 struct malloc_readonly mopts;
182 u_char _pad[MALLOC_PAGESIZE];
183} malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE)));
184#define mopts malloc_readonly.mopts
185#define g_pool mopts.g_pool
186
187char *malloc_options; /* compile-time options */
188
189static char *malloc_func; /* current function */
190static int malloc_active; /* status of malloc */
191
192static size_t malloc_guarded; /* bytes used for guards */
193static size_t malloc_used; /* bytes allocated */
194
195static size_t rnibblesused; /* random nibbles used */
196static u_char rbytes[512]; /* random bytes */
197static u_char getrnibble(void);
198
199extern char *__progname;
200
201#ifdef MALLOC_STATS
202void malloc_dump(int);
203static void malloc_exit(void);
204#define CALLER __builtin_return_address(0)
205#else
206#define CALLER NULL
207#endif
208
209/* low bits of r->p determine size: 0 means >= page size and p->size holding
210 * real size, otherwise r->size is a shift count, or 1 for malloc(0)
211 */
212#define REALSIZE(sz, r) \
213 (sz) = (uintptr_t)(r)->p & MALLOC_PAGEMASK, \
214 (sz) = ((sz) == 0 ? (r)->size : ((sz) == 1 ? 0 : (1 << ((sz)-1))))
215
216static inline size_t
217hash(void *p)
218{
219 size_t sum;
220 union {
221 uintptr_t p;
222 unsigned short a[sizeof(void *) / sizeof(short)];
223 } u;
224 u.p = (uintptr_t)p >> MALLOC_PAGESHIFT;
225 sum = u.a[0];
226 sum = (sum << 7) - sum + u.a[1];
227#ifdef __LP64__
228 sum = (sum << 7) - sum + u.a[2];
229 sum = (sum << 7) - sum + u.a[3];
230#endif
231 return sum;
232}
233
234static void
235wrterror(char *msg, void *p)
236{
237 char *q = " error: ";
238 struct iovec iov[6];
239 char buf[20];
240 int saved_errno = errno;
241
242 iov[0].iov_base = __progname;
243 iov[0].iov_len = strlen(__progname);
244 iov[1].iov_base = malloc_func;
245 iov[1].iov_len = strlen(malloc_func);
246 iov[2].iov_base = q;
247 iov[2].iov_len = strlen(q);
248 iov[3].iov_base = msg;
249 iov[3].iov_len = strlen(msg);
250 iov[4].iov_base = buf;
251 if (p == NULL)
252 iov[4].iov_len = 0;
253 else {
254 snprintf(buf, sizeof(buf), " %p", p);
255 iov[4].iov_len = strlen(buf);
256 }
257 iov[5].iov_base = "\n";
258 iov[5].iov_len = 1;
259 writev(STDERR_FILENO, iov, 6);
260
261#ifdef MALLOC_STATS
262 if (mopts.malloc_stats)
263 malloc_dump(STDERR_FILENO);
264#endif /* MALLOC_STATS */
265
266 errno = saved_errno;
267 if (mopts.malloc_abort)
268 abort();
269}
270
271static void
272rbytes_init(void)
273{
274 arc4random_buf(rbytes, sizeof(rbytes));
275 rnibblesused = 0;
276}
277
278static inline u_char
279getrnibble(void)
280{
281 u_char x;
282
283 if (rnibblesused >= 2 * sizeof(rbytes))
284 rbytes_init();
285 x = rbytes[rnibblesused++ / 2];
286 return (rnibblesused & 1 ? x & 0xf : x >> 4);
287}
288
289/*
290 * Cache maintenance. We keep at most malloc_cache pages cached.
291 * If the cache is becoming full, unmap pages in the cache for real,
292 * and then add the region to the cache
293 * Opposed to the regular region data structure, the sizes in the
294 * cache are in MALLOC_PAGESIZE units.
295 */
296static void
297unmap(struct dir_info *d, void *p, size_t sz)
298{
299 size_t psz = sz >> MALLOC_PAGESHIFT;
300 size_t rsz, tounmap;
301 struct region_info *r;
302 u_int i, offset;
303
304 if (sz != PAGEROUND(sz)) {
305 wrterror("munmap round", NULL);
306 return;
307 }
308
309 if (psz > mopts.malloc_cache) {
310 if (munmap(p, sz))
311 wrterror("munmap", p);
312 malloc_used -= sz;
313 return;
314 }
315 tounmap = 0;
316 rsz = mopts.malloc_cache - d->free_regions_size;
317 if (psz > rsz)
318 tounmap = psz - rsz;
319 offset = getrnibble() + (getrnibble() << 4);
320 for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) {
321 r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
322 if (r->p != NULL) {
323 rsz = r->size << MALLOC_PAGESHIFT;
324 if (munmap(r->p, rsz))
325 wrterror("munmap", r->p);
326 r->p = NULL;
327 if (tounmap > r->size)
328 tounmap -= r->size;
329 else
330 tounmap = 0;
331 d->free_regions_size -= r->size;
332 r->size = 0;
333 malloc_used -= rsz;
334 }
335 }
336 if (tounmap > 0)
337 wrterror("malloc cache underflow", NULL);
338 for (i = 0; i < mopts.malloc_cache; i++) {
339 r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
340 if (r->p == NULL) {
341 if (mopts.malloc_hint)
342 madvise(p, sz, MADV_FREE);
343 if (mopts.malloc_freeunmap)
344 mprotect(p, sz, PROT_NONE);
345 r->p = p;
346 r->size = psz;
347 d->free_regions_size += psz;
348 break;
349 }
350 }
351 if (i == mopts.malloc_cache)
352 wrterror("malloc free slot lost", NULL);
353 if (d->free_regions_size > mopts.malloc_cache)
354 wrterror("malloc cache overflow", NULL);
355}
356
357static void
358zapcacheregion(struct dir_info *d, void *p, size_t len)
359{
360 u_int i;
361 struct region_info *r;
362 size_t rsz;
363
364 for (i = 0; i < mopts.malloc_cache; i++) {
365 r = &d->free_regions[i];
366 if (r->p >= p && r->p <= (void *)((char *)p + len)) {
367 rsz = r->size << MALLOC_PAGESHIFT;
368 if (munmap(r->p, rsz))
369 wrterror("munmap", r->p);
370 r->p = NULL;
371 d->free_regions_size -= r->size;
372 r->size = 0;
373 malloc_used -= rsz;
374 }
375 }
376}
377
378static void *
379map(struct dir_info *d, size_t sz, int zero_fill)
380{
381 size_t psz = sz >> MALLOC_PAGESHIFT;
382 struct region_info *r, *big = NULL;
383 u_int i, offset;
384 void *p;
385
386 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
387 d->canary1 != ~d->canary2)
388 wrterror("internal struct corrupt", NULL);
389 if (sz != PAGEROUND(sz)) {
390 wrterror("map round", NULL);
391 return MAP_FAILED;
392 }
393 if (psz > d->free_regions_size) {
394 p = MMAP(sz);
395 if (p != MAP_FAILED)
396 malloc_used += sz;
397 /* zero fill not needed */
398 return p;
399 }
400 offset = getrnibble() + (getrnibble() << 4);
401 for (i = 0; i < mopts.malloc_cache; i++) {
402 r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
403 if (r->p != NULL) {
404 if (r->size == psz) {
405 p = r->p;
406 if (mopts.malloc_freeunmap)
407 mprotect(p, sz, PROT_READ | PROT_WRITE);
408 if (mopts.malloc_hint)
409 madvise(p, sz, MADV_NORMAL);
410 r->p = NULL;
411 r->size = 0;
412 d->free_regions_size -= psz;
413 if (zero_fill)
414 memset(p, 0, sz);
415 else if (mopts.malloc_junk &&
416 mopts.malloc_freeunmap)
417 memset(p, SOME_FREEJUNK, sz);
418 return p;
419 } else if (r->size > psz)
420 big = r;
421 }
422 }
423 if (big != NULL) {
424 r = big;
425 p = (char *)r->p + ((r->size - psz) << MALLOC_PAGESHIFT);
426 if (mopts.malloc_freeunmap)
427 mprotect(p, sz, PROT_READ | PROT_WRITE);
428 if (mopts.malloc_hint)
429 madvise(p, sz, MADV_NORMAL);
430 r->size -= psz;
431 d->free_regions_size -= psz;
432 if (zero_fill)
433 memset(p, 0, sz);
434 else if (mopts.malloc_junk && mopts.malloc_freeunmap)
435 memset(p, SOME_FREEJUNK, sz);
436 return p;
437 }
438 p = MMAP(sz);
439 if (p != MAP_FAILED)
440 malloc_used += sz;
441 if (d->free_regions_size > mopts.malloc_cache)
442 wrterror("malloc cache", NULL);
443 /* zero fill not needed */
444 return p;
445}
446
447/*
448 * Initialize a dir_info, which should have been cleared by caller
449 */
450static int
451omalloc_init(struct dir_info **dp)
452{
453 char *p, b[64];
454 int i, j;
455 size_t d_avail, regioninfo_size;
456 struct dir_info *d;
457
458 rbytes_init();
459
460 /*
461 * Default options
462 */
463 mopts.malloc_abort = 1;
464 mopts.malloc_move = 1;
465 mopts.malloc_cache = MALLOC_DEFAULT_CACHE;
466
467 for (i = 0; i < 3; i++) {
468 switch (i) {
469 case 0:
470 j = readlink("/etc/malloc.conf", b, sizeof b - 1);
471 if (j <= 0)
472 continue;
473 b[j] = '\0';
474 p = b;
475 break;
476 case 1:
477 if (issetugid() == 0)
478 p = getenv("MALLOC_OPTIONS");
479 else
480 continue;
481 break;
482 case 2:
483 p = malloc_options;
484 break;
485 default:
486 p = NULL;
487 }
488
489 for (; p != NULL && *p != '\0'; p++) {
490 switch (*p) {
491 case '>':
492 mopts.malloc_cache <<= 1;
493 if (mopts.malloc_cache > MALLOC_MAXCACHE)
494 mopts.malloc_cache = MALLOC_MAXCACHE;
495 break;
496 case '<':
497 mopts.malloc_cache >>= 1;
498 break;
499 case 'a':
500 mopts.malloc_abort = 0;
501 break;
502 case 'A':
503 mopts.malloc_abort = 1;
504 break;
505#ifdef MALLOC_STATS
506 case 'd':
507 mopts.malloc_stats = 0;
508 break;
509 case 'D':
510 mopts.malloc_stats = 1;
511 break;
512#endif /* MALLOC_STATS */
513 case 'f':
514 mopts.malloc_freenow = 0;
515 mopts.malloc_freeunmap = 0;
516 break;
517 case 'F':
518 mopts.malloc_freenow = 1;
519 mopts.malloc_freeunmap = 1;
520 break;
521 case 'g':
522 mopts.malloc_guard = 0;
523 break;
524 case 'G':
525 mopts.malloc_guard = MALLOC_PAGESIZE;
526 break;
527 case 'h':
528 mopts.malloc_hint = 0;
529 break;
530 case 'H':
531 mopts.malloc_hint = 1;
532 break;
533 case 'j':
534 mopts.malloc_junk = 0;
535 break;
536 case 'J':
537 mopts.malloc_junk = 1;
538 break;
539 case 'n':
540 case 'N':
541 break;
542 case 'p':
543 mopts.malloc_move = 0;
544 break;
545 case 'P':
546 mopts.malloc_move = 1;
547 break;
548 case 'r':
549 mopts.malloc_realloc = 0;
550 break;
551 case 'R':
552 mopts.malloc_realloc = 1;
553 break;
554 case 's':
555 mopts.malloc_freeunmap = mopts.malloc_junk = 0;
556 mopts.malloc_guard = 0;
557 mopts.malloc_cache = MALLOC_DEFAULT_CACHE;
558 break;
559 case 'S':
560 mopts.malloc_freeunmap = mopts.malloc_junk = 1;
561 mopts.malloc_guard = MALLOC_PAGESIZE;
562 mopts.malloc_cache = 0;
563 break;
564 case 'u':
565 mopts.malloc_freeunmap = 0;
566 break;
567 case 'U':
568 mopts.malloc_freeunmap = 1;
569 break;
570 case 'x':
571 mopts.malloc_xmalloc = 0;
572 break;
573 case 'X':
574 mopts.malloc_xmalloc = 1;
575 break;
576 case 'z':
577 mopts.malloc_zero = 0;
578 break;
579 case 'Z':
580 mopts.malloc_zero = 1;
581 break;
582 default: {
583 static const char q[] = "malloc() warning: "
584 "unknown char in MALLOC_OPTIONS\n";
585 write(STDERR_FILENO, q, sizeof(q) - 1);
586 break;
587 }
588 }
589 }
590 }
591
592 /*
593 * We want junk in the entire allocation, and zero only in the part
594 * the user asked for.
595 */
596 if (mopts.malloc_zero)
597 mopts.malloc_junk = 1;
598
599#ifdef MALLOC_STATS
600 if (mopts.malloc_stats && (atexit(malloc_exit) == -1)) {
601 static const char q[] = "malloc() warning: atexit(2) failed."
602 " Will not be able to dump stats on exit\n";
603 write(STDERR_FILENO, q, sizeof(q) - 1);
604 }
605#endif /* MALLOC_STATS */
606
607 while ((mopts.malloc_canary = arc4random()) == 0)
608 ;
609
610 /*
611 * Allocate dir_info with a guard page on either side. Also
612 * randomise offset inside the page at which the dir_info
613 * lies (subject to alignment by 1 << MALLOC_MINSHIFT)
614 */
615 if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
616 return -1;
617 mprotect(p, MALLOC_PAGESIZE, PROT_NONE);
618 mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ,
619 MALLOC_PAGESIZE, PROT_NONE);
620 d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT;
621 d = (struct dir_info *)(p + MALLOC_PAGESIZE +
622 (arc4random_uniform(d_avail) << MALLOC_MINSHIFT));
623
624 d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS;
625 regioninfo_size = d->regions_total * sizeof(struct region_info);
626 d->r = MMAP(regioninfo_size);
627 if (d->r == MAP_FAILED) {
628 wrterror("malloc init mmap failed", NULL);
629 d->regions_total = 0;
630 return 1;
631 }
632 for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
633 LIST_INIT(&d->chunk_info_list[i]);
634 LIST_INIT(&d->chunk_dir[i]);
635 }
636 malloc_used += regioninfo_size;
637 d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d;
638 d->canary2 = ~d->canary1;
639
640 *dp = d;
641
642 /*
643 * Options have been set and will never be reset.
644 * Prevent further tampering with them.
645 */
646 if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
647 mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ);
648
649 return 0;
650}
651
652static int
653omalloc_grow(struct dir_info *d)
654{
655 size_t newtotal;
656 size_t newsize;
657 size_t mask;
658 size_t i;
659 struct region_info *p;
660
661 if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 )
662 return 1;
663
664 newtotal = d->regions_total * 2;
665 newsize = newtotal * sizeof(struct region_info);
666 mask = newtotal - 1;
667
668 p = MMAP(newsize);
669 if (p == MAP_FAILED)
670 return 1;
671
672 malloc_used += newsize;
673 memset(p, 0, newsize);
674 STATS_ZERO(d->inserts);
675 STATS_ZERO(d->insert_collisions);
676 for (i = 0; i < d->regions_total; i++) {
677 void *q = d->r[i].p;
678 if (q != NULL) {
679 size_t index = hash(q) & mask;
680 STATS_INC(d->inserts);
681 while (p[index].p != NULL) {
682 index = (index - 1) & mask;
683 STATS_INC(d->insert_collisions);
684 }
685 p[index] = d->r[i];
686 }
687 }
688 /* avoid pages containing meta info to end up in cache */
689 if (munmap(d->r, d->regions_total * sizeof(struct region_info)))
690 wrterror("munmap", d->r);
691 else
692 malloc_used -= d->regions_total * sizeof(struct region_info);
693 d->regions_free = d->regions_free + d->regions_total;
694 d->regions_total = newtotal;
695 d->r = p;
696 return 0;
697}
698
699static struct chunk_info *
700alloc_chunk_info(struct dir_info *d, int bits)
701{
702 struct chunk_info *p;
703 size_t size, count;
704
705 if (bits == 0)
706 count = MALLOC_PAGESIZE / MALLOC_MINSIZE;
707 else
708 count = MALLOC_PAGESIZE >> bits;
709
710 size = howmany(count, MALLOC_BITS);
711 size = sizeof(struct chunk_info) + (size - 1) * sizeof(u_short);
712 size = ALIGN(size);
713
714 if (LIST_EMPTY(&d->chunk_info_list[bits])) {
715 char *q;
716 int i;
717
718 q = MMAP(MALLOC_PAGESIZE);
719 if (q == MAP_FAILED)
720 return NULL;
721 malloc_used += MALLOC_PAGESIZE;
722 count = MALLOC_PAGESIZE / size;
723 for (i = 0; i < count; i++, q += size)
724 LIST_INSERT_HEAD(&d->chunk_info_list[bits],
725 (struct chunk_info *)q, entries);
726 }
727 p = LIST_FIRST(&d->chunk_info_list[bits]);
728 LIST_REMOVE(p, entries);
729 memset(p, 0, size);
730 p->canary = d->canary1;
731 return p;
732}
733
734
735/*
736 * The hashtable uses the assumption that p is never NULL. This holds since
737 * non-MAP_FIXED mappings with hint 0 start at BRKSIZ.
738 */
739static int
740insert(struct dir_info *d, void *p, size_t sz, void *f)
741{
742 size_t index;
743 size_t mask;
744 void *q;
745
746 if (d->regions_free * 4 < d->regions_total) {
747 if (omalloc_grow(d))
748 return 1;
749 }
750 mask = d->regions_total - 1;
751 index = hash(p) & mask;
752 q = d->r[index].p;
753 STATS_INC(d->inserts);
754 while (q != NULL) {
755 index = (index - 1) & mask;
756 q = d->r[index].p;
757 STATS_INC(d->insert_collisions);
758 }
759 d->r[index].p = p;
760 d->r[index].size = sz;
761#ifdef MALLOC_STATS
762 d->r[index].f = f;
763#endif
764 d->regions_free--;
765 return 0;
766}
767
768static struct region_info *
769find(struct dir_info *d, void *p)
770{
771 size_t index;
772 size_t mask = d->regions_total - 1;
773 void *q, *r;
774
775 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
776 d->canary1 != ~d->canary2)
777 wrterror("internal struct corrupt", NULL);
778 p = MASK_POINTER(p);
779 index = hash(p) & mask;
780 r = d->r[index].p;
781 q = MASK_POINTER(r);
782 STATS_INC(d->finds);
783 while (q != p && r != NULL) {
784 index = (index - 1) & mask;
785 r = d->r[index].p;
786 q = MASK_POINTER(r);
787 STATS_INC(d->find_collisions);
788 }
789 return (q == p && r != NULL) ? &d->r[index] : NULL;
790}
791
792static void
793delete(struct dir_info *d, struct region_info *ri)
794{
795 /* algorithm R, Knuth Vol III section 6.4 */
796 size_t mask = d->regions_total - 1;
797 size_t i, j, r;
798
799 if (d->regions_total & (d->regions_total - 1))
800 wrterror("regions_total not 2^x", NULL);
801 d->regions_free++;
802 STATS_INC(g_pool->deletes);
803
804 i = ri - d->r;
805 for (;;) {
806 d->r[i].p = NULL;
807 d->r[i].size = 0;
808 j = i;
809 for (;;) {
810 i = (i - 1) & mask;
811 if (d->r[i].p == NULL)
812 return;
813 r = hash(d->r[i].p) & mask;
814 if ((i <= r && r < j) || (r < j && j < i) ||
815 (j < i && i <= r))
816 continue;
817 d->r[j] = d->r[i];
818 STATS_INC(g_pool->delete_moves);
819 break;
820 }
821
822 }
823}
824
825/*
826 * Allocate a page of chunks
827 */
828static struct chunk_info *
829omalloc_make_chunks(struct dir_info *d, int bits)
830{
831 struct chunk_info *bp;
832 void *pp;
833 int i, k;
834
835 /* Allocate a new bucket */
836 pp = map(d, MALLOC_PAGESIZE, 0);
837 if (pp == MAP_FAILED)
838 return NULL;
839
840 bp = alloc_chunk_info(d, bits);
841 if (bp == NULL) {
842 unmap(d, pp, MALLOC_PAGESIZE);
843 return NULL;
844 }
845
846 /* memory protect the page allocated in the malloc(0) case */
847 if (bits == 0) {
848 bp->size = 0;
849 bp->shift = 1;
850 i = MALLOC_MINSIZE - 1;
851 while (i >>= 1)
852 bp->shift++;
853 bp->total = bp->free = MALLOC_PAGESIZE >> bp->shift;
854 bp->page = pp;
855
856 k = mprotect(pp, MALLOC_PAGESIZE, PROT_NONE);
857 if (k < 0) {
858 unmap(d, pp, MALLOC_PAGESIZE);
859 LIST_INSERT_HEAD(&d->chunk_info_list[0], bp, entries);
860 return NULL;
861 }
862 } else {
863 bp->size = 1U << bits;
864 bp->shift = bits;
865 bp->total = bp->free = MALLOC_PAGESIZE >> bits;
866 bp->page = pp;
867 }
868
869 /* set all valid bits in the bitmap */
870 k = bp->total;
871 i = 0;
872
873 /* Do a bunch at a time */
874 for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS)
875 bp->bits[i / MALLOC_BITS] = (u_short)~0U;
876
877 for (; i < k; i++)
878 bp->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS);
879
880 LIST_INSERT_HEAD(&d->chunk_dir[bits], bp, entries);
881
882 bits++;
883 if ((uintptr_t)pp & bits)
884 wrterror("pp & bits", pp);
885
886 insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp, NULL);
887 return bp;
888}
889
890
891/*
892 * Allocate a chunk
893 */
894static void *
895malloc_bytes(struct dir_info *d, size_t size, void *f)
896{
897 int i, j;
898 size_t k;
899 u_short u, *lp;
900 struct chunk_info *bp;
901
902 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
903 d->canary1 != ~d->canary2)
904 wrterror("internal struct corrupt", NULL);
905 /* Don't bother with anything less than this */
906 /* unless we have a malloc(0) requests */
907 if (size != 0 && size < MALLOC_MINSIZE)
908 size = MALLOC_MINSIZE;
909
910 /* Find the right bucket */
911 if (size == 0)
912 j = 0;
913 else {
914 j = MALLOC_MINSHIFT;
915 i = (size - 1) >> (MALLOC_MINSHIFT - 1);
916 while (i >>= 1)
917 j++;
918 }
919
920 /* If it's empty, make a page more of that size chunks */
921 if (LIST_EMPTY(&d->chunk_dir[j])) {
922 bp = omalloc_make_chunks(d, j);
923 if (bp == NULL)
924 return NULL;
925 } else
926 bp = LIST_FIRST(&d->chunk_dir[j]);
927
928 if (bp->canary != d->canary1)
929 wrterror("chunk info corrupted", NULL);
930
931 i = d->chunk_start;
932 if (bp->free > 1)
933 i += getrnibble();
934 if (i >= bp->total)
935 i &= bp->total - 1;
936 for (;;) {
937 for (;;) {
938 lp = &bp->bits[i / MALLOC_BITS];
939 if (!*lp) {
940 i += MALLOC_BITS;
941 i &= ~(MALLOC_BITS - 1);
942 if (i >= bp->total)
943 i = 0;
944 } else
945 break;
946 }
947 k = i % MALLOC_BITS;
948 u = 1 << k;
949 if (*lp & u)
950 break;
951 if (++i >= bp->total)
952 i = 0;
953 }
954 d->chunk_start += i + 1;
955#ifdef MALLOC_STATS
956 if (i == 0) {
957 struct region_info *r = find(d, bp->page);
958 r->f = f;
959 }
960#endif
961
962 *lp ^= u;
963
964 /* If there are no more free, remove from free-list */
965 if (!--bp->free)
966 LIST_REMOVE(bp, entries);
967
968 /* Adjust to the real offset of that chunk */
969 k += (lp - bp->bits) * MALLOC_BITS;
970 k <<= bp->shift;
971
972 if (mopts.malloc_junk && bp->size > 0)
973 memset((char *)bp->page + k, SOME_JUNK, bp->size);
974 return ((char *)bp->page + k);
975}
976
977
978/*
979 * Free a chunk, and possibly the page it's on, if the page becomes empty.
980 */
981static void
982free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
983{
984 struct chunk_head *mp;
985 struct chunk_info *info;
986 int i;
987
988 info = (struct chunk_info *)r->size;
989 if (info->canary != d->canary1)
990 wrterror("chunk info corrupted", NULL);
991
992 /* Find the chunk number on the page */
993 i = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
994
995 if ((uintptr_t)ptr & ((1U << (info->shift)) - 1)) {
996 wrterror("modified chunk-pointer", ptr);
997 return;
998 }
999 if (info->bits[i / MALLOC_BITS] & (1U << (i % MALLOC_BITS))) {
1000 wrterror("chunk is already free", ptr);
1001 return;
1002 }
1003
1004 info->bits[i / MALLOC_BITS] |= 1U << (i % MALLOC_BITS);
1005 info->free++;
1006
1007 if (info->size != 0)
1008 mp = d->chunk_dir + info->shift;
1009 else
1010 mp = d->chunk_dir;
1011
1012 if (info->free == 1) {
1013 /* Page became non-full */
1014 LIST_INSERT_HEAD(mp, info, entries);
1015 return;
1016 }
1017 if (info->free != info->total)
1018 return;
1019
1020 LIST_REMOVE(info, entries);
1021
1022 if (info->size == 0 && !mopts.malloc_freeunmap)
1023 mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE);
1024 unmap(d, info->page, MALLOC_PAGESIZE);
1025
1026 delete(d, r);
1027 if (info->size != 0)
1028 mp = &d->chunk_info_list[info->shift];
1029 else
1030 mp = &d->chunk_info_list[0];
1031 LIST_INSERT_HEAD(mp, info, entries);
1032}
1033
1034
1035
1036static void *
1037omalloc(size_t sz, int zero_fill, void *f)
1038{
1039 void *p;
1040 size_t psz;
1041
1042 if (sz > MALLOC_MAXCHUNK) {
1043 if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
1044 errno = ENOMEM;
1045 return NULL;
1046 }
1047 sz += mopts.malloc_guard;
1048 psz = PAGEROUND(sz);
1049 p = map(g_pool, psz, zero_fill);
1050 if (p == MAP_FAILED) {
1051 errno = ENOMEM;
1052 return NULL;
1053 }
1054 if (insert(g_pool, p, sz, f)) {
1055 unmap(g_pool, p, psz);
1056 errno = ENOMEM;
1057 return NULL;
1058 }
1059 if (mopts.malloc_guard) {
1060 if (mprotect((char *)p + psz - mopts.malloc_guard,
1061 mopts.malloc_guard, PROT_NONE))
1062 wrterror("mprotect", NULL);
1063 malloc_guarded += mopts.malloc_guard;
1064 }
1065
1066 if (mopts.malloc_move &&
1067 sz - mopts.malloc_guard < MALLOC_PAGESIZE -
1068 MALLOC_LEEWAY) {
1069 /* fill whole allocation */
1070 if (mopts.malloc_junk)
1071 memset(p, SOME_JUNK, psz - mopts.malloc_guard);
1072 /* shift towards the end */
1073 p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_LEEWAY -
1074 (sz - mopts.malloc_guard)) & ~(MALLOC_MINSIZE-1));
1075 /* fill zeros if needed and overwritten above */
1076 if (zero_fill && mopts.malloc_junk)
1077 memset(p, 0, sz - mopts.malloc_guard);
1078 } else {
1079 if (mopts.malloc_junk) {
1080 if (zero_fill)
1081 memset((char *)p + sz - mopts.malloc_guard,
1082 SOME_JUNK, psz - sz);
1083 else
1084 memset(p, SOME_JUNK,
1085 psz - mopts.malloc_guard);
1086 }
1087 }
1088
1089 } else {
1090 /* takes care of SOME_JUNK */
1091 p = malloc_bytes(g_pool, sz, f);
1092 if (zero_fill && p != NULL && sz > 0)
1093 memset(p, 0, sz);
1094 }
1095
1096 return p;
1097}
1098
1099/*
1100 * Common function for handling recursion. Only
1101 * print the error message once, to avoid making the problem
1102 * potentially worse.
1103 */
1104static void
1105malloc_recurse(void)
1106{
1107 static int noprint;
1108
1109 if (noprint == 0) {
1110 noprint = 1;
1111 wrterror("recursive call", NULL);
1112 }
1113 malloc_active--;
1114 _MALLOC_UNLOCK();
1115 errno = EDEADLK;
1116}
1117
1118static int
1119malloc_init(void)
1120{
1121 if (omalloc_init(&g_pool)) {
1122 _MALLOC_UNLOCK();
1123 if (mopts.malloc_xmalloc)
1124 wrterror("out of memory", NULL);
1125 errno = ENOMEM;
1126 return -1;
1127 }
1128 return 0;
1129}
1130
1131void *
1132malloc(size_t size)
1133{
1134 void *r;
1135 int saved_errno = errno;
1136
1137 _MALLOC_LOCK();
1138 malloc_func = " in malloc():";
1139 if (g_pool == NULL) {
1140 if (malloc_init() != 0)
1141 return NULL;
1142 }
1143 if (malloc_active++) {
1144 malloc_recurse();
1145 return NULL;
1146 }
1147 r = omalloc(size, mopts.malloc_zero, CALLER);
1148 malloc_active--;
1149 _MALLOC_UNLOCK();
1150 if (r == NULL && mopts.malloc_xmalloc) {
1151 wrterror("out of memory", NULL);
1152 errno = ENOMEM;
1153 }
1154 if (r != NULL)
1155 errno = saved_errno;
1156 return r;
1157}
1158
1159static void
1160ofree(void *p)
1161{
1162 struct region_info *r;
1163 size_t sz;
1164
1165 r = find(g_pool, p);
1166 if (r == NULL) {
1167 wrterror("bogus pointer (double free?)", p);
1168 return;
1169 }
1170 REALSIZE(sz, r);
1171 if (sz > MALLOC_MAXCHUNK) {
1172 if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE -
1173 MALLOC_LEEWAY) {
1174 if (r->p != p) {
1175 wrterror("bogus pointer", p);
1176 return;
1177 }
1178 } else {
1179#if notyetbecause_of_realloc
1180 /* shifted towards the end */
1181 if (p != ((char *)r->p) + ((MALLOC_PAGESIZE -
1182 MALLOC_MINSIZE - sz - mopts.malloc_guard) &
1183 ~(MALLOC_MINSIZE-1))) {
1184 }
1185#endif
1186 p = r->p;
1187 }
1188 if (mopts.malloc_guard) {
1189 if (sz < mopts.malloc_guard)
1190 wrterror("guard size", NULL);
1191 if (!mopts.malloc_freeunmap) {
1192 if (mprotect((char *)p + PAGEROUND(sz) -
1193 mopts.malloc_guard, mopts.malloc_guard,
1194 PROT_READ | PROT_WRITE))
1195 wrterror("mprotect", NULL);
1196 }
1197 malloc_guarded -= mopts.malloc_guard;
1198 }
1199 if (mopts.malloc_junk && !mopts.malloc_freeunmap)
1200 memset(p, SOME_FREEJUNK,
1201 PAGEROUND(sz) - mopts.malloc_guard);
1202 unmap(g_pool, p, PAGEROUND(sz));
1203 delete(g_pool, r);
1204 } else {
1205 void *tmp;
1206 int i;
1207
1208 if (mopts.malloc_junk && sz > 0)
1209 memset(p, SOME_FREEJUNK, sz);
1210 if (!mopts.malloc_freenow) {
1211 i = getrnibble();
1212 tmp = p;
1213 p = g_pool->delayed_chunks[i];
1214 g_pool->delayed_chunks[i] = tmp;
1215 }
1216 if (p != NULL) {
1217 r = find(g_pool, p);
1218 if (r == NULL) {
1219 wrterror("bogus pointer (double free?)", p);
1220 return;
1221 }
1222 free_bytes(g_pool, r, p);
1223 }
1224 }
1225}
1226
1227void
1228free(void *ptr)
1229{
1230 int saved_errno = errno;
1231
1232 /* This is legal. */
1233 if (ptr == NULL)
1234 return;
1235
1236 _MALLOC_LOCK();
1237 malloc_func = " in free():";
1238 if (g_pool == NULL) {
1239 _MALLOC_UNLOCK();
1240 wrterror("free() called before allocation", NULL);
1241 return;
1242 }
1243 if (malloc_active++) {
1244 malloc_recurse();
1245 return;
1246 }
1247 ofree(ptr);
1248 malloc_active--;
1249 _MALLOC_UNLOCK();
1250 errno = saved_errno;
1251}
1252
1253
1254static void *
1255orealloc(void *p, size_t newsz, void *f)
1256{
1257 struct region_info *r;
1258 size_t oldsz, goldsz, gnewsz;
1259 void *q;
1260
1261 if (p == NULL)
1262 return omalloc(newsz, 0, f);
1263
1264 r = find(g_pool, p);
1265 if (r == NULL) {
1266 wrterror("bogus pointer (double free?)", p);
1267 return NULL;
1268 }
1269 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
1270 errno = ENOMEM;
1271 return NULL;
1272 }
1273
1274 REALSIZE(oldsz, r);
1275 goldsz = oldsz;
1276 if (oldsz > MALLOC_MAXCHUNK) {
1277 if (oldsz < mopts.malloc_guard)
1278 wrterror("guard size", NULL);
1279 oldsz -= mopts.malloc_guard;
1280 }
1281
1282 gnewsz = newsz;
1283 if (gnewsz > MALLOC_MAXCHUNK)
1284 gnewsz += mopts.malloc_guard;
1285
1286 if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p &&
1287 !mopts.malloc_realloc) {
1288 size_t roldsz = PAGEROUND(goldsz);
1289 size_t rnewsz = PAGEROUND(gnewsz);
1290
1291 if (rnewsz > roldsz) {
1292 if (!mopts.malloc_guard) {
1293 void *hint = (char *)p + roldsz;
1294 size_t needed = rnewsz - roldsz;
1295
1296 STATS_INC(g_pool->cheap_realloc_tries);
1297 zapcacheregion(g_pool, hint, needed);
1298 q = MQUERY(hint, needed);
1299 if (q == hint)
1300 q = MMAPA(hint, needed);
1301 else
1302 q = MAP_FAILED;
1303 if (q == hint) {
1304 malloc_used += needed;
1305 if (mopts.malloc_junk)
1306 memset(q, SOME_JUNK, needed);
1307 r->size = newsz;
1308 STATS_SETF(r, f);
1309 STATS_INC(g_pool->cheap_reallocs);
1310 return p;
1311 } else if (q != MAP_FAILED) {
1312 if (munmap(q, needed))
1313 wrterror("munmap", q);
1314 }
1315 }
1316 } else if (rnewsz < roldsz) {
1317 if (mopts.malloc_guard) {
1318 if (mprotect((char *)p + roldsz -
1319 mopts.malloc_guard, mopts.malloc_guard,
1320 PROT_READ | PROT_WRITE))
1321 wrterror("mprotect", NULL);
1322 if (mprotect((char *)p + rnewsz -
1323 mopts.malloc_guard, mopts.malloc_guard,
1324 PROT_NONE))
1325 wrterror("mprotect", NULL);
1326 }
1327 unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz);
1328 r->size = gnewsz;
1329 STATS_SETF(r, f);
1330 return p;
1331 } else {
1332 if (newsz > oldsz && mopts.malloc_junk)
1333 memset((char *)p + newsz, SOME_JUNK,
1334 rnewsz - mopts.malloc_guard - newsz);
1335 r->size = gnewsz;
1336 STATS_SETF(r, f);
1337 return p;
1338 }
1339 }
1340 if (newsz <= oldsz && newsz > oldsz / 2 && !mopts.malloc_realloc) {
1341 if (mopts.malloc_junk && newsz > 0)
1342 memset((char *)p + newsz, SOME_JUNK, oldsz - newsz);
1343 STATS_SETF(r, f);
1344 return p;
1345 } else if (newsz != oldsz || mopts.malloc_realloc) {
1346 q = omalloc(newsz, 0, f);
1347 if (q == NULL)
1348 return NULL;
1349 if (newsz != 0 && oldsz != 0)
1350 memcpy(q, p, oldsz < newsz ? oldsz : newsz);
1351 ofree(p);
1352 return q;
1353 } else {
1354 STATS_SETF(r, f);
1355 return p;
1356 }
1357}
1358
1359void *
1360realloc(void *ptr, size_t size)
1361{
1362 void *r;
1363 int saved_errno = errno;
1364
1365 _MALLOC_LOCK();
1366 malloc_func = " in realloc():";
1367 if (g_pool == NULL) {
1368 if (malloc_init() != 0)
1369 return NULL;
1370 }
1371 if (malloc_active++) {
1372 malloc_recurse();
1373 return NULL;
1374 }
1375 r = orealloc(ptr, size, CALLER);
1376
1377 malloc_active--;
1378 _MALLOC_UNLOCK();
1379 if (r == NULL && mopts.malloc_xmalloc) {
1380 wrterror("out of memory", NULL);
1381 errno = ENOMEM;
1382 }
1383 if (r != NULL)
1384 errno = saved_errno;
1385 return r;
1386}
1387
1388
1389#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
1390
1391void *
1392calloc(size_t nmemb, size_t size)
1393{
1394 void *r;
1395 int saved_errno = errno;
1396
1397 _MALLOC_LOCK();
1398 malloc_func = " in calloc():";
1399 if (g_pool == NULL) {
1400 if (malloc_init() != 0)
1401 return NULL;
1402 }
1403 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1404 nmemb > 0 && SIZE_MAX / nmemb < size) {
1405 _MALLOC_UNLOCK();
1406 if (mopts.malloc_xmalloc)
1407 wrterror("out of memory", NULL);
1408 errno = ENOMEM;
1409 return NULL;
1410 }
1411
1412 if (malloc_active++) {
1413 malloc_recurse();
1414 return NULL;
1415 }
1416
1417 size *= nmemb;
1418 r = omalloc(size, 1, CALLER);
1419
1420 malloc_active--;
1421 _MALLOC_UNLOCK();
1422 if (r == NULL && mopts.malloc_xmalloc) {
1423 wrterror("out of memory", NULL);
1424 errno = ENOMEM;
1425 }
1426 if (r != NULL)
1427 errno = saved_errno;
1428 return r;
1429}
1430
1431static void *
1432mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill)
1433{
1434 char *p, *q;
1435
1436 if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0) {
1437 wrterror("mapalign bad alignment", NULL);
1438 return MAP_FAILED;
1439 }
1440 if (sz != PAGEROUND(sz)) {
1441 wrterror("mapalign round", NULL);
1442 return MAP_FAILED;
1443 }
1444
1445 /* Allocate sz + alignment bytes of memory, which must include a
1446 * subrange of size bytes that is properly aligned. Unmap the
1447 * other bytes, and then return that subrange.
1448 */
1449
1450 /* We need sz + alignment to fit into a size_t. */
1451 if (alignment > SIZE_MAX - sz)
1452 return MAP_FAILED;
1453
1454 p = map(d, sz + alignment, zero_fill);
1455 if (p == MAP_FAILED)
1456 return MAP_FAILED;
1457 q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1));
1458 if (q != p) {
1459 if (munmap(p, q - p))
1460 wrterror("munmap", p);
1461 }
1462 if (munmap(q + sz, alignment - (q - p)))
1463 wrterror("munmap", q + sz);
1464 malloc_used -= alignment;
1465
1466 return q;
1467}
1468
1469static void *
1470omemalign(size_t alignment, size_t sz, int zero_fill, void *f)
1471{
1472 size_t psz;
1473 void *p;
1474
1475 if (alignment <= MALLOC_PAGESIZE) {
1476 /*
1477 * max(size, alignment) is enough to assure the requested alignment,
1478 * since the allocator always allocates power-of-two blocks.
1479 */
1480 if (sz < alignment)
1481 sz = alignment;
1482 return omalloc(sz, zero_fill, f);
1483 }
1484
1485 if (sz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
1486 errno = ENOMEM;
1487 return NULL;
1488 }
1489
1490 sz += mopts.malloc_guard;
1491 psz = PAGEROUND(sz);
1492
1493 p = mapalign(g_pool, alignment, psz, zero_fill);
1494 if (p == NULL) {
1495 errno = ENOMEM;
1496 return NULL;
1497 }
1498
1499 if (insert(g_pool, p, sz, f)) {
1500 unmap(g_pool, p, psz);
1501 errno = ENOMEM;
1502 return NULL;
1503 }
1504
1505 if (mopts.malloc_guard) {
1506 if (mprotect((char *)p + psz - mopts.malloc_guard,
1507 mopts.malloc_guard, PROT_NONE))
1508 wrterror("mprotect", NULL);
1509 malloc_guarded += mopts.malloc_guard;
1510 }
1511
1512 if (mopts.malloc_junk) {
1513 if (zero_fill)
1514 memset((char *)p + sz - mopts.malloc_guard,
1515 SOME_JUNK, psz - sz);
1516 else
1517 memset(p, SOME_JUNK, psz - mopts.malloc_guard);
1518 }
1519
1520 return p;
1521}
1522
1523int
1524posix_memalign(void **memptr, size_t alignment, size_t size)
1525{
1526 int res, saved_errno = errno;
1527 void *r;
1528
1529 /* Make sure that alignment is a large enough power of 2. */
1530 if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *))
1531 return EINVAL;
1532
1533 _MALLOC_LOCK();
1534 malloc_func = " in posix_memalign():";
1535 if (g_pool == NULL) {
1536 if (malloc_init() != 0)
1537 goto err;
1538 }
1539 if (malloc_active++) {
1540 malloc_recurse();
1541 goto err;
1542 }
1543 r = omemalign(alignment, size, mopts.malloc_zero, CALLER);
1544 malloc_active--;
1545 _MALLOC_UNLOCK();
1546 if (r == NULL) {
1547 if (mopts.malloc_xmalloc) {
1548 wrterror("out of memory", NULL);
1549 errno = ENOMEM;
1550 }
1551 goto err;
1552 }
1553 errno = saved_errno;
1554 *memptr = r;
1555 return 0;
1556
1557err:
1558 res = errno;
1559 errno = saved_errno;
1560 return res;
1561}
1562
1563#ifdef MALLOC_STATS
1564
1565struct malloc_leak {
1566 void (*f)();
1567 size_t total_size;
1568 int count;
1569};
1570
1571struct leaknode {
1572 RB_ENTRY(leaknode) entry;
1573 struct malloc_leak d;
1574};
1575
1576static int
1577leakcmp(struct leaknode *e1, struct leaknode *e2)
1578{
1579 return e1->d.f < e2->d.f ? -1 : e1->d.f > e2->d.f;
1580}
1581
1582static RB_HEAD(leaktree, leaknode) leakhead;
1583RB_GENERATE_STATIC(leaktree, leaknode, entry, leakcmp)
1584
1585static void
1586putleakinfo(void *f, size_t sz, int cnt)
1587{
1588 struct leaknode key, *p;
1589 static struct leaknode *page;
1590 static int used;
1591
1592 if (cnt == 0)
1593 return;
1594
1595 key.d.f = f;
1596 p = RB_FIND(leaktree, &leakhead, &key);
1597 if (p == NULL) {
1598 if (page == NULL ||
1599 used >= MALLOC_PAGESIZE / sizeof(struct leaknode)) {
1600 page = MMAP(MALLOC_PAGESIZE);
1601 if (page == MAP_FAILED)
1602 return;
1603 used = 0;
1604 }
1605 p = &page[used++];
1606 p->d.f = f;
1607 p->d.total_size = sz * cnt;
1608 p->d.count = cnt;
1609 RB_INSERT(leaktree, &leakhead, p);
1610 } else {
1611 p->d.total_size += sz * cnt;
1612 p->d.count += cnt;
1613 }
1614}
1615
1616static struct malloc_leak *malloc_leaks;
1617
1618static void
1619dump_leaks(int fd)
1620{
1621 struct leaknode *p;
1622 char buf[64];
1623 int i = 0;
1624
1625 snprintf(buf, sizeof(buf), "Leak report\n");
1626 write(fd, buf, strlen(buf));
1627 snprintf(buf, sizeof(buf), " f sum # avg\n");
1628 write(fd, buf, strlen(buf));
1629 /* XXX only one page of summary */
1630 if (malloc_leaks == NULL)
1631 malloc_leaks = MMAP(MALLOC_PAGESIZE);
1632 if (malloc_leaks != MAP_FAILED)
1633 memset(malloc_leaks, 0, MALLOC_PAGESIZE);
1634 RB_FOREACH(p, leaktree, &leakhead) {
1635 snprintf(buf, sizeof(buf), "%12p %7zu %6u %6zu\n", p->d.f,
1636 p->d.total_size, p->d.count, p->d.total_size / p->d.count);
1637 write(fd, buf, strlen(buf));
1638 if (malloc_leaks == MAP_FAILED ||
1639 i >= MALLOC_PAGESIZE / sizeof(struct malloc_leak))
1640 continue;
1641 malloc_leaks[i].f = p->d.f;
1642 malloc_leaks[i].total_size = p->d.total_size;
1643 malloc_leaks[i].count = p->d.count;
1644 i++;
1645 }
1646}
1647
1648static void
1649dump_chunk(int fd, struct chunk_info *p, void *f, int fromfreelist)
1650{
1651 char buf[64];
1652
1653 while (p != NULL) {
1654 snprintf(buf, sizeof(buf), "chunk %12p %12p %4d %d/%d\n",
1655 p->page, ((p->bits[0] & 1) ? NULL : f),
1656 p->size, p->free, p->total);
1657 write(fd, buf, strlen(buf));
1658 if (!fromfreelist) {
1659 if (p->bits[0] & 1)
1660 putleakinfo(NULL, p->size, p->total - p->free);
1661 else {
1662 putleakinfo(f, p->size, 1);
1663 putleakinfo(NULL, p->size,
1664 p->total - p->free - 1);
1665 }
1666 break;
1667 }
1668 p = LIST_NEXT(p, entries);
1669 if (p != NULL) {
1670 snprintf(buf, sizeof(buf), " ");
1671 write(fd, buf, strlen(buf));
1672 }
1673 }
1674}
1675
1676static void
1677dump_free_chunk_info(int fd, struct dir_info *d)
1678{
1679 char buf[64];
1680 int i, count;
1681
1682 snprintf(buf, sizeof(buf), "Free chunk structs:\n");
1683 write(fd, buf, strlen(buf));
1684 for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
1685 struct chunk_info *p;
1686
1687 count = 0;
1688 LIST_FOREACH(p, &d->chunk_info_list[i], entries)
1689 count++;
1690 p = LIST_FIRST(&d->chunk_dir[i]);
1691 if (p == NULL && count == 0)
1692 continue;
1693 snprintf(buf, sizeof(buf), "%2d) %3d ", i, count);
1694 write(fd, buf, strlen(buf));
1695 if (p != NULL)
1696 dump_chunk(fd, p, NULL, 1);
1697 else
1698 write(fd, "\n", 1);
1699 }
1700
1701}
1702
1703static void
1704dump_free_page_info(int fd, struct dir_info *d)
1705{
1706 char buf[64];
1707 int i;
1708
1709 snprintf(buf, sizeof(buf), "Free pages cached: %zu\n",
1710 d->free_regions_size);
1711 write(fd, buf, strlen(buf));
1712 for (i = 0; i < mopts.malloc_cache; i++) {
1713 if (d->free_regions[i].p != NULL) {
1714 snprintf(buf, sizeof(buf), "%2d) ", i);
1715 write(fd, buf, strlen(buf));
1716 snprintf(buf, sizeof(buf), "free at %p: %zu\n",
1717 d->free_regions[i].p, d->free_regions[i].size);
1718 write(fd, buf, strlen(buf));
1719 }
1720 }
1721}
1722
1723static void
1724malloc_dump1(int fd, struct dir_info *d)
1725{
1726 char buf[64];
1727 size_t i, realsize;
1728
1729 snprintf(buf, sizeof(buf), "Malloc dir of %s at %p\n", __progname, d);
1730 write(fd, buf, strlen(buf));
1731 if (d == NULL)
1732 return;
1733 snprintf(buf, sizeof(buf), "Region slots free %zu/%zu\n",
1734 d->regions_free, d->regions_total);
1735 write(fd, buf, strlen(buf));
1736 snprintf(buf, sizeof(buf), "Finds %zu/%zu\n", d->finds,
1737 d->find_collisions);
1738 write(fd, buf, strlen(buf));
1739 snprintf(buf, sizeof(buf), "Inserts %zu/%zu\n", d->inserts,
1740 d->insert_collisions);
1741 write(fd, buf, strlen(buf));
1742 snprintf(buf, sizeof(buf), "Deletes %zu/%zu\n", d->deletes,
1743 d->delete_moves);
1744 write(fd, buf, strlen(buf));
1745 snprintf(buf, sizeof(buf), "Cheap reallocs %zu/%zu\n",
1746 d->cheap_reallocs, d->cheap_realloc_tries);
1747 write(fd, buf, strlen(buf));
1748 dump_free_chunk_info(fd, d);
1749 dump_free_page_info(fd, d);
1750 snprintf(buf, sizeof(buf),
1751 "slot) hash d type page f size [free/n]\n");
1752 write(fd, buf, strlen(buf));
1753 for (i = 0; i < d->regions_total; i++) {
1754 if (d->r[i].p != NULL) {
1755 size_t h = hash(d->r[i].p) &
1756 (d->regions_total - 1);
1757 snprintf(buf, sizeof(buf), "%4zx) #%4zx %zd ",
1758 i, h, h - i);
1759 write(fd, buf, strlen(buf));
1760 REALSIZE(realsize, &d->r[i]);
1761 if (realsize > MALLOC_MAXCHUNK) {
1762 putleakinfo(d->r[i].f, realsize, 1);
1763 snprintf(buf, sizeof(buf),
1764 "pages %12p %12p %zu\n", d->r[i].p,
1765 d->r[i].f, realsize);
1766 write(fd, buf, strlen(buf));
1767 } else
1768 dump_chunk(fd,
1769 (struct chunk_info *)d->r[i].size,
1770 d->r[i].f, 0);
1771 }
1772 }
1773 snprintf(buf, sizeof(buf), "In use %zu\n", malloc_used);
1774 write(fd, buf, strlen(buf));
1775 snprintf(buf, sizeof(buf), "Guarded %zu\n", malloc_guarded);
1776 write(fd, buf, strlen(buf));
1777 dump_leaks(fd);
1778 write(fd, "\n", 1);
1779}
1780
1781void
1782malloc_dump(int fd)
1783{
1784 int i;
1785 void *p;
1786 struct region_info *r;
1787 int saved_errno = errno;
1788
1789 for (i = 0; i <= MALLOC_DELAYED_CHUNKS; i++) {
1790 p = g_pool->delayed_chunks[i];
1791 if (p == NULL)
1792 continue;
1793 r = find(g_pool, p);
1794 if (r == NULL)
1795 wrterror("bogus pointer in malloc_dump", p);
1796 free_bytes(g_pool, r, p);
1797 g_pool->delayed_chunks[i] = NULL;
1798 }
1799 /* XXX leak when run multiple times */
1800 RB_INIT(&leakhead);
1801 malloc_dump1(fd, g_pool);
1802 errno = saved_errno;
1803}
1804
1805static void
1806malloc_exit(void)
1807{
1808 static const char q[] = "malloc() warning: Couldn't dump stats\n";
1809 int save_errno = errno, fd;
1810
1811 fd = open("malloc.out", O_RDWR|O_APPEND);
1812 if (fd != -1) {
1813 malloc_dump(fd);
1814 close(fd);
1815 } else
1816 write(STDERR_FILENO, q, sizeof(q) - 1);
1817 errno = save_errno;
1818}
1819
1820#endif /* MALLOC_STATS */
diff --git a/src/lib/libc/stdlib/merge.c b/src/lib/libc/stdlib/merge.c
new file mode 100644
index 0000000000..43ef8b08e2
--- /dev/null
+++ b/src/lib/libc/stdlib/merge.c
@@ -0,0 +1,333 @@
1/* $OpenBSD: merge.c,v 1.9 2011/03/06 00:55:38 deraadt Exp $ */
2/*-
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Peter McIlroy.
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/*
35 * Hybrid exponential search/linear search merge sort with hybrid
36 * natural/pairwise first pass. Requires about .3% more comparisons
37 * for random data than LSMS with pairwise first pass alone.
38 * It works for objects as small as two bytes.
39 */
40
41#define NATURAL
42#define THRESHOLD 16 /* Best choice for natural merge cut-off. */
43
44/* #define NATURAL to get hybrid natural merge.
45 * (The default is pairwise merging.)
46 */
47
48#include <sys/types.h>
49
50#include <errno.h>
51#include <stdlib.h>
52#include <string.h>
53
54static void setup(u_char *, u_char *, size_t, size_t, int (*)());
55static void insertionsort(u_char *, size_t, size_t, int (*)());
56
57#define ISIZE sizeof(int)
58#define PSIZE sizeof(u_char *)
59#define ICOPY_LIST(src, dst, last) \
60 do \
61 *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \
62 while(src < last)
63#define ICOPY_ELT(src, dst, i) \
64 do \
65 *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \
66 while (i -= ISIZE)
67
68#define CCOPY_LIST(src, dst, last) \
69 do \
70 *dst++ = *src++; \
71 while (src < last)
72#define CCOPY_ELT(src, dst, i) \
73 do \
74 *dst++ = *src++; \
75 while (i -= 1)
76
77/*
78 * Find the next possible pointer head. (Trickery for forcing an array
79 * to do double duty as a linked list when objects do not align with word
80 * boundaries.
81 */
82/* Assumption: PSIZE is a power of 2. */
83#define EVAL(p) (u_char **) \
84 ((u_char *)0 + \
85 (((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
86
87/*
88 * Arguments are as for qsort.
89 */
90int
91mergesort(void *base, size_t nmemb, size_t size,
92 int (*cmp)(const void *, const void *))
93{
94 int i, sense;
95 int big, iflag;
96 u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
97 u_char *list2, *list1, *p2, *p, *last, **p1;
98
99 if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
100 errno = EINVAL;
101 return (-1);
102 }
103
104 /*
105 * XXX
106 * Stupid subtraction for the Cray.
107 */
108 iflag = 0;
109 if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
110 iflag = 1;
111
112 if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
113 return (-1);
114
115 list1 = base;
116 setup(list1, list2, nmemb, size, cmp);
117 last = list2 + nmemb * size;
118 i = big = 0;
119 while (*EVAL(list2) != last) {
120 l2 = list1;
121 p1 = EVAL(list1);
122 for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
123 p2 = *EVAL(p2);
124 f1 = l2;
125 f2 = l1 = list1 + (p2 - list2);
126 if (p2 != last)
127 p2 = *EVAL(p2);
128 l2 = list1 + (p2 - list2);
129 while (f1 < l1 && f2 < l2) {
130 if ((*cmp)(f1, f2) <= 0) {
131 q = f2;
132 b = f1, t = l1;
133 sense = -1;
134 } else {
135 q = f1;
136 b = f2, t = l2;
137 sense = 0;
138 }
139 if (!big) { /* here i = 0 */
140 while ((b += size) < t && cmp(q, b) >sense)
141 if (++i == 6) {
142 big = 1;
143 goto EXPONENTIAL;
144 }
145 } else {
146EXPONENTIAL: for (i = size; ; i <<= 1)
147 if ((p = (b + i)) >= t) {
148 if ((p = t - size) > b &&
149 (*cmp)(q, p) <= sense)
150 t = p;
151 else
152 b = p;
153 break;
154 } else if ((*cmp)(q, p) <= sense) {
155 t = p;
156 if (i == size)
157 big = 0;
158 goto FASTCASE;
159 } else
160 b = p;
161 while (t > b+size) {
162 i = (((t - b) / size) >> 1) * size;
163 if ((*cmp)(q, p = b + i) <= sense)
164 t = p;
165 else
166 b = p;
167 }
168 goto COPY;
169FASTCASE: while (i > size)
170 if ((*cmp)(q,
171 p = b + (i >>= 1)) <= sense)
172 t = p;
173 else
174 b = p;
175COPY: b = t;
176 }
177 i = size;
178 if (q == f1) {
179 if (iflag) {
180 ICOPY_LIST(f2, tp2, b);
181 ICOPY_ELT(f1, tp2, i);
182 } else {
183 CCOPY_LIST(f2, tp2, b);
184 CCOPY_ELT(f1, tp2, i);
185 }
186 } else {
187 if (iflag) {
188 ICOPY_LIST(f1, tp2, b);
189 ICOPY_ELT(f2, tp2, i);
190 } else {
191 CCOPY_LIST(f1, tp2, b);
192 CCOPY_ELT(f2, tp2, i);
193 }
194 }
195 }
196 if (f2 < l2) {
197 if (iflag)
198 ICOPY_LIST(f2, tp2, l2);
199 else
200 CCOPY_LIST(f2, tp2, l2);
201 } else if (f1 < l1) {
202 if (iflag)
203 ICOPY_LIST(f1, tp2, l1);
204 else
205 CCOPY_LIST(f1, tp2, l1);
206 }
207 *p1 = l2;
208 }
209 tp2 = list1; /* swap list1, list2 */
210 list1 = list2;
211 list2 = tp2;
212 last = list2 + nmemb*size;
213 }
214 if (base == list2) {
215 memmove(list2, list1, nmemb*size);
216 list2 = list1;
217 }
218 free(list2);
219 return (0);
220}
221
222#define swap(a, b) { \
223 s = b; \
224 i = size; \
225 do { \
226 tmp = *a; *a++ = *s; *s++ = tmp; \
227 } while (--i); \
228 a -= size; \
229 }
230#define reverse(bot, top) { \
231 s = top; \
232 do { \
233 i = size; \
234 do { \
235 tmp = *bot; *bot++ = *s; *s++ = tmp; \
236 } while (--i); \
237 s -= size2; \
238 } while(bot < s); \
239}
240
241/*
242 * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of
243 * increasing order, list2 in a corresponding linked list. Checks for runs
244 * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL
245 * is defined. Otherwise simple pairwise merging is used.)
246 */
247void
248setup(u_char *list1, u_char *list2, size_t n, size_t size,
249 int (*cmp)(const void *, const void *))
250{
251 int i, length, size2, sense;
252 u_char tmp, *f1, *f2, *s, *l2, *last, *p2;
253
254 size2 = size*2;
255 if (n <= 5) {
256 insertionsort(list1, n, size, cmp);
257 *EVAL(list2) = (u_char*) list2 + n*size;
258 return;
259 }
260 /*
261 * Avoid running pointers out of bounds; limit n to evens
262 * for simplicity.
263 */
264 i = 4 + (n & 1);
265 insertionsort(list1 + (n - i) * size, i, size, cmp);
266 last = list1 + size * (n - i);
267 *EVAL(list2 + (last - list1)) = list2 + n * size;
268
269#ifdef NATURAL
270 p2 = list2;
271 f1 = list1;
272 sense = (cmp(f1, f1 + size) > 0);
273 for (; f1 < last; sense = !sense) {
274 length = 2;
275 /* Find pairs with same sense. */
276 for (f2 = f1 + size2; f2 < last; f2 += size2) {
277 if ((cmp(f2, f2+ size) > 0) != sense)
278 break;
279 length += 2;
280 }
281 if (length < THRESHOLD) { /* Pairwise merge */
282 do {
283 p2 = *EVAL(p2) = f1 + size2 - list1 + list2;
284 if (sense > 0)
285 swap (f1, f1 + size);
286 } while ((f1 += size2) < f2);
287 } else { /* Natural merge */
288 l2 = f2;
289 for (f2 = f1 + size2; f2 < l2; f2 += size2) {
290 if ((cmp(f2-size, f2) > 0) != sense) {
291 p2 = *EVAL(p2) = f2 - list1 + list2;
292 if (sense > 0)
293 reverse(f1, f2-size);
294 f1 = f2;
295 }
296 }
297 if (sense > 0)
298 reverse (f1, f2-size);
299 f1 = f2;
300 if (f2 < last || cmp(f2 - size, f2) > 0)
301 p2 = *EVAL(p2) = f2 - list1 + list2;
302 else
303 p2 = *EVAL(p2) = list2 + n*size;
304 }
305 }
306#else /* pairwise merge only. */
307 for (f1 = list1, p2 = list2; f1 < last; f1 += size2) {
308 p2 = *EVAL(p2) = p2 + size2;
309 if (cmp (f1, f1 + size) > 0)
310 swap(f1, f1 + size);
311 }
312#endif /* NATURAL */
313}
314
315/*
316 * This is to avoid out-of-bounds addresses in sorting the
317 * last 4 elements.
318 */
319static void
320insertionsort(u_char *a, size_t n, size_t size,
321 int (*cmp)(const void *, const void *))
322{
323 u_char *ai, *s, *t, *u, tmp;
324 int i;
325
326 for (ai = a+size; --n >= 1; ai += size)
327 for (t = ai; t > a; t -= size) {
328 u = t - size;
329 if (cmp(u, t) <= 0)
330 break;
331 swap(u, t);
332 }
333}
diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c
new file mode 100644
index 0000000000..977264aba5
--- /dev/null
+++ b/src/lib/libc/stdlib/mrand48.c
@@ -0,0 +1,24 @@
1/* $OpenBSD: mrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18
19long
20mrand48(void)
21{
22 __dorand48(__rand48_seed);
23 return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1];
24}
diff --git a/src/lib/libc/stdlib/nrand48.c b/src/lib/libc/stdlib/nrand48.c
new file mode 100644
index 0000000000..f1f548c3af
--- /dev/null
+++ b/src/lib/libc/stdlib/nrand48.c
@@ -0,0 +1,22 @@
1/* $OpenBSD: nrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17long
18nrand48(unsigned short xseed[3])
19{
20 __dorand48(xseed);
21 return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
22}
diff --git a/src/lib/libc/stdlib/posix_memalign.3 b/src/lib/libc/stdlib/posix_memalign.3
new file mode 100644
index 0000000000..05ec1b9d14
--- /dev/null
+++ b/src/lib/libc/stdlib/posix_memalign.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: posix_memalign.3,v 1.3 2012/06/18 17:03:52 matthew Exp $
2.\" Copyright (C) 2006 Jason Evans <jasone@FreeBSD.org>.
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice(s), this list of conditions and the following disclaimer as
10.\" the first lines of this file unmodified other than the possible
11.\" addition of one or more copyright notices.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice(s), this list of conditions and the following disclaimer in
14.\" the documentation and/or other materials provided with the
15.\" distribution.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
18.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
21.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.\" $FreeBSD: src/lib/libc/stdlib/posix_memalign.3,v 1.3 2007/03/28 04:32:51 jasone Exp $
30.\"
31.Dd $Mdocdate: June 18 2012 $
32.Dt POSIX_MEMALIGN 3
33.Os
34.Sh NAME
35.Nm posix_memalign
36.Nd aligned memory allocation
37.Sh SYNOPSIS
38.In stdlib.h
39.Ft int
40.Fn posix_memalign "void **ptr" "size_t alignment" "size_t size"
41.Sh DESCRIPTION
42The
43.Fn posix_memalign
44function allocates
45.Fa size
46bytes of memory such that the allocation's base address is a multiple of
47.Fa alignment ,
48and returns the allocation in the value pointed to by
49.Fa ptr .
50.Pp
51The requested
52.Fa alignment
53must be a power of 2 at least as large as
54.Fn sizeof "void *" .
55.Pp
56Memory that is allocated via
57.Fn posix_memalign
58can be used as an argument in subsequent calls to
59.Xr realloc 3
60and
61.Xr free 3 .
62.Sh RETURN VALUES
63The
64.Fn posix_memalign
65function returns the value 0 if successful; otherwise it returns an error value.
66.Sh ERRORS
67The
68.Fn posix_memalign
69function will fail if:
70.Bl -tag -width Er
71.It Bq Er EINVAL
72The
73.Fa alignment
74parameter is not a power of 2 at least as large as
75.Fn sizeof "void *" .
76.It Bq Er ENOMEM
77Memory allocation error.
78.El
79.Sh SEE ALSO
80.Xr free 3 ,
81.Xr malloc 3 ,
82.Xr realloc 3
83.Sh STANDARDS
84The
85.Fn posix_memalign
86function conforms to
87.St -p1003.1-2001 .
88.Sh HISTORY
89The
90.Fn posix_memalign
91function first appeared in
92.Ox 4.8 .
diff --git a/src/lib/libc/stdlib/posix_openpt.3 b/src/lib/libc/stdlib/posix_openpt.3
new file mode 100644
index 0000000000..376772bb07
--- /dev/null
+++ b/src/lib/libc/stdlib/posix_openpt.3
@@ -0,0 +1,102 @@
1.\" $OpenBSD: posix_openpt.3,v 1.3 2012/12/05 06:40:59 jmc Exp $
2.\"
3.\" Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: December 5 2012 $
18.Dt POSIX_OPENPT 3
19.Os
20.Sh NAME
21.Nm posix_openpt
22.Nd open a pseudo-terminal device
23.Sh SYNOPSIS
24.In stdlib.h
25.In fcntl.h
26.Ft int
27.Fn posix_openpt "int oflag"
28.Sh DESCRIPTION
29The
30.Fn posix_openpt
31function finds the next available pseudo-terminal and returns an open
32file descriptor for its master device.
33The path name of the slave device may be determined via the
34.Fn ptsname
35function.
36Note that the
37.Fn unlockpt
38and
39.Fn grantpt
40functions should be called before opening the slave device.
41.Pp
42The
43.Ar oflag
44argument is formed by bitwise-inclusive
45.Tn OR Ns 'ing
46the following values defined in
47.In fcntl.h :
48.Bl -tag -width O_NOCTTY -offset indent
49.It Dv O_RDWR
50Open for reading and writing.
51.It Dv O_NOCTTY
52Prevent the device from being made the controlling terminal for the session.
53This flag has no effect on
54.Ox
55and is included for compatibility with other systems.
56.El
57.Pp
58The
59.Dv O_RDWR
60flag must be specified in
61.Fa oflag .
62If
63.Fa oflag
64contains values other than those listed above,
65.Fn posix_openpt
66will return an error.
67.Sh RETURN VALUES
68If successful,
69.Fn posix_openpt
70returns a non-negative integer, the file descriptor for the
71pseudo-terminal master device.
72Otherwise, a value of \-1 is returned and
73.Va errno
74is set to indicate the error.
75.Sh ERRORS
76The
77.Fn posix_openpt
78function will fail if:
79.Bl -tag -width Er
80.It Bq Er EMFILE
81The per-process descriptor table is full.
82.It Bq Er ENFILE
83The system file table is full.
84.It Bq Er EINVAL
85The value of
86.Fa oflag
87is not valid.
88.El
89.Sh SEE ALSO
90.Xr ptsname 3 ,
91.Xr pty 4 ,
92.Xr tty 4
93.Sh STANDARDS
94The
95.Fn posix_openpt
96function conforms to
97.St -p1003.1-2001 .
98.Sh HISTORY
99The
100.Fn posix_openpt
101function appeared in
102.Ox 5.3 .
diff --git a/src/lib/libc/stdlib/posix_pty.c b/src/lib/libc/stdlib/posix_pty.c
new file mode 100644
index 0000000000..a2025ddbb6
--- /dev/null
+++ b/src/lib/libc/stdlib/posix_pty.c
@@ -0,0 +1,119 @@
1/* $OpenBSD: posix_pty.c,v 1.1 2012/12/03 20:08:33 millert Exp $ */
2
3/*
4 * Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/ioctl.h>
21#include <sys/stat.h>
22#include <sys/tty.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <paths.h>
26#include <stddef.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30
31int
32posix_openpt(int oflag)
33{
34 struct ptmget ptm;
35 int fd, mfd = -1;
36
37 /* User must specify O_RDWR in oflag. */
38 if (!(oflag & O_RDWR)) {
39 errno = EINVAL;
40 return -1;
41 }
42
43 /* Get pty master and slave (this API only uses the master). */
44 fd = open(PATH_PTMDEV, O_RDWR);
45 if (fd != -1) {
46 if (ioctl(fd, PTMGET, &ptm) != -1) {
47 close(ptm.sfd);
48 mfd = ptm.cfd;
49 }
50 close(fd);
51 }
52
53 return mfd;
54}
55
56/*
57 * Look up the name of the specified pty master fd.
58 * Note that the name returned does *not* include the /dev/ prefix.
59 * Returns the name on success and NULL on error, setting errno.
60 */
61static const char *
62ptmname(int mfd)
63{
64 struct stat sb;
65 const char *name;
66
67 /* Make sure it is a pty master. */
68 if (fstat(mfd, &sb) != 0)
69 return NULL;
70 if (!S_ISCHR(sb.st_mode)) {
71 errno = EINVAL;
72 return NULL;
73 }
74 name = devname(sb.st_rdev, S_IFCHR);
75 if (strncmp(name, "pty", 3) != 0) {
76 errno = EINVAL;
77 return NULL;
78 }
79 return name;
80}
81
82/*
83 * The PTMGET ioctl handles the mode and owner for us.
84 */
85int
86grantpt(int mfd)
87{
88 return ptmname(mfd) ? 0 : -1;
89}
90
91/*
92 * The PTMGET ioctl unlocks the pty master and slave for us.
93 */
94int
95unlockpt(int mfd)
96{
97 return ptmname(mfd) ? 0 : -1;
98}
99
100/*
101 * Look up the path of the slave pty that corresponds to the master fd.
102 * Returns the path if successful or NULL on error.
103 */
104char *
105ptsname(int mfd)
106{
107 const char *master;
108 static char slave[sizeof(((struct ptmget *)NULL)->sn)];
109
110 if ((master = ptmname(mfd)) == NULL)
111 return NULL;
112
113 /* Add /dev/ prefix and convert "pty" to "tty". */
114 strlcpy(slave, _PATH_DEV, sizeof(slave));
115 strlcat(slave, master, sizeof(slave));
116 slave[sizeof(_PATH_DEV) - 1] = 't';
117
118 return slave;
119}
diff --git a/src/lib/libc/stdlib/ptsname.3 b/src/lib/libc/stdlib/ptsname.3
new file mode 100644
index 0000000000..98705528f5
--- /dev/null
+++ b/src/lib/libc/stdlib/ptsname.3
@@ -0,0 +1,160 @@
1.\" $OpenBSD: ptsname.3,v 1.2 2012/12/04 18:42:16 millert Exp $
2.\"
3.\" Copyright (c) 2002 The FreeBSD Project, Inc.
4.\" All rights reserved.
5.\"
6.\" This software includes code contributed to the FreeBSD Project
7.\" by Ryan Younce of North Carolina State University.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\" notice, this list of conditions and the following disclaimer in the
16.\" documentation and/or other materials provided with the distribution.
17.\" 3. Neither the name of the FreeBSD Project nor the names of its
18.\" contributors may be used to endorse or promote products derived from
19.\" this software without specific prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT AND CONTRIBUTORS
22.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT
25.\" OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32.\"
33.\" $FreeBSD: head/lib/libc/stdlib/ptsname.3 240412 2012-09-12 17:54:09Z emaste $
34.\"
35.Dd $Mdocdate: December 4 2012 $
36.Dt PTSNAME 3
37.Os
38.Sh NAME
39.Nm grantpt ,
40.Nm ptsname ,
41.Nm unlockpt
42.Nd pseudo-terminal access functions
43.Sh SYNOPSIS
44.In stdlib.h
45.Ft int
46.Fn grantpt "int fildes"
47.Ft "char *"
48.Fn ptsname "int fildes"
49.Ft int
50.Fn unlockpt "int fildes"
51.Sh DESCRIPTION
52The
53.Fn grantpt ,
54.Fn ptsname ,
55and
56.Fn unlockpt
57functions allow access to pseudo-terminal devices.
58These three functions accept a file descriptor that references the
59master half of a pseudo-terminal pair.
60This file descriptor is created with
61.Xr posix_openpt 3 .
62.Pp
63The
64.Fn grantpt
65function is used to establish ownership and permissions
66of the slave device counterpart to the master device
67specified with
68.Fa fildes .
69The slave device's ownership is set to the real user ID
70of the calling process, and the permissions are set to
71user readable-writable and group writable.
72The group owner of the slave device is also set to the
73group
74.Dq Li tty .
75.Pp
76The
77.Fn ptsname
78function returns the full path name of the slave device
79counterpart to the master device specified with
80.Fa fildes .
81This value can be used
82to subsequently open the appropriate slave after
83.Xr posix_openpt 3
84and
85.Fn grantpt
86have been called.
87.Pp
88The
89.Fn unlockpt
90function clears the lock held on the pseudo-terminal pair
91for the master device specified with
92.Fa fildes .
93.Sh RETURN VALUES
94.Rv -std grantpt unlockpt
95.Pp
96The
97.Fn ptsname
98function returns a pointer to the name
99of the slave device on success; otherwise a
100.Dv NULL
101pointer is returned.
102.Sh ERRORS
103The
104.Fn grantpt ,
105.Fn ptsname
106and
107.Fn unlockpt
108functions may fail and set
109.Va errno
110to:
111.Bl -tag -width Er
112.It Bq Er EBADF
113.Fa fildes
114is not a valid open file descriptor.
115.It Bq Er EINVAL
116.Fa fildes
117is not a master pseudo-terminal device.
118.El
119.Pp
120In addition, the
121.Fn grantpt
122function may set
123.Va errno
124to:
125.Bl -tag -width Er
126.It Bq Er EACCES
127The slave pseudo-terminal device could not be accessed.
128.El
129.Sh SEE ALSO
130.Xr posix_openpt 3 ,
131.Xr pty 4 ,
132.Xr tty 4
133.Sh STANDARDS
134The
135.Fn ptsname
136function conforms to
137.St -p1003.1-2008 .
138.Pp
139This implementation of
140.Fn grantpt
141and
142.Fn unlockpt
143does not conform to
144.St -p1003.1-2008 ,
145because it depends on
146.Xr posix_openpt 3
147to create the pseudo-terminal device with proper permissions in place.
148It only validates whether
149.Fa fildes
150is a valid pseudo-terminal master device.
151Future revisions of the specification will likely allow this behaviour,
152as stated by the Austin Group.
153.Sh HISTORY
154The
155.Fn grantpt ,
156.Fn ptsname
157and
158.Fn unlockpt
159functions appeared in
160.Ox 5.3 .
diff --git a/src/lib/libc/stdlib/qabs.3 b/src/lib/libc/stdlib/qabs.3
new file mode 100644
index 0000000000..6703072e72
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.3
@@ -0,0 +1,56 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: qabs.3,v 1.13 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt QABS 3
36.Os
37.Sh NAME
38.Nm qabs
39.Nd return the absolute value of a quad integer
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft quad_t
43.Fn qabs "quad_t j"
44.Sh DESCRIPTION
45The
46.Fn qabs
47function returns the absolute value of the quad integer
48.Fa j .
49.Sh SEE ALSO
50.Xr abs 3 ,
51.Xr cabs 3 ,
52.Xr floor 3 ,
53.Xr imaxabs 3 ,
54.Xr labs 3
55.Sh BUGS
56The absolute value of the most negative integer remains negative.
diff --git a/src/lib/libc/stdlib/qabs.c b/src/lib/libc/stdlib/qabs.c
new file mode 100644
index 0000000000..656b93c822
--- /dev/null
+++ b/src/lib/libc/stdlib/qabs.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: qabs.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <stdlib.h>
32
33quad_t
34qabs(quad_t j)
35{
36 return(j < 0 ? -j : j);
37}
diff --git a/src/lib/libc/stdlib/qdiv.3 b/src/lib/libc/stdlib/qdiv.3
new file mode 100644
index 0000000000..5f5275493e
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.3
@@ -0,0 +1,61 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: qdiv.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt QDIV 3
36.Os
37.Sh NAME
38.Nm qdiv
39.Nd return quotient and remainder from division
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft qdiv_t
43.Fn qdiv "quad_t num" "quad_t denom"
44.Sh DESCRIPTION
45The
46.Fn qdiv
47function computes the value
48.Fa num Ns / Ns Fa denom
49and returns the quotient and remainder in a structure named
50.Li qdiv_t
51that contains two
52.Li quad integer
53members named
54.Fa quot
55and
56.Fa rem .
57.Sh SEE ALSO
58.Xr div 3 ,
59.Xr imaxdiv 3 ,
60.Xr ldiv 3 ,
61.Xr lldiv 3
diff --git a/src/lib/libc/stdlib/qdiv.c b/src/lib/libc/stdlib/qdiv.c
new file mode 100644
index 0000000000..f3db0915ed
--- /dev/null
+++ b/src/lib/libc/stdlib/qdiv.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: qdiv.c,v 1.5 2005/08/08 08:05:37 espie 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> /* qdiv_t */
35
36qdiv_t
37qdiv(quad_t num, quad_t denom)
38{
39 qdiv_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/qsort.3 b/src/lib/libc/stdlib/qsort.3
new file mode 100644
index 0000000000..4481a96ee4
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.3
@@ -0,0 +1,238 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: qsort.3,v 1.17 2013/07/17 05:42:11 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt QSORT 3
36.Os
37.Sh NAME
38.Nm qsort ,
39.Nm heapsort ,
40.Nm mergesort
41.Nd sort functions
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft void
45.Fn qsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
46.Ft int
47.Fn heapsort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
48.Ft int
49.Fn mergesort "void *base" "size_t nmemb" "size_t size" "int (*compar)(const void *, const void *)"
50.Sh DESCRIPTION
51The
52.Fn qsort
53function is a modified partition-exchange sort, or quicksort.
54The
55.Fn heapsort
56function is a modified selection sort.
57The
58.Fn mergesort
59function is a modified merge sort with exponential search
60intended for sorting data with pre-existing order.
61.Pp
62The
63.Fn qsort
64and
65.Fn heapsort
66functions sort an array of
67.Fa nmemb
68objects, the initial member of which is pointed to by
69.Fa base .
70The size of each object is specified by
71.Fa size .
72.Fn mergesort
73behaves similarly, but
74.Em requires
75that
76.Fa size
77be greater than
78.Dq "sizeof(void *) / 2" .
79.Pp
80The contents of the array
81.Fa base
82are sorted in ascending order according to
83a comparison function pointed to by
84.Fa compar ,
85which requires two arguments pointing to the objects being
86compared.
87.Pp
88The comparison function must return an integer less than, equal to, or
89greater than zero if the first argument is considered to be respectively
90less than, equal to, or greater than the second.
91.Pp
92The functions
93.Fn qsort
94and
95.Fn heapsort
96are
97.Em not
98stable, that is, if two members compare as equal, their order in
99the sorted array is undefined.
100The function
101.Fn mergesort
102is stable.
103.Pp
104The
105.Fn qsort
106function is an implementation of C.A.R. Hoare's
107.Dq quicksort
108algorithm,
109a variant of partition-exchange sorting; in particular, see D.E. Knuth's
110Algorithm Q.
111.Fn qsort
112takes O N lg N average time.
113This implementation uses median selection to avoid its
114O N**2 worst-case behavior.
115.Pp
116The
117.Fn heapsort
118function is an implementation of J.W.J. William's
119.Dq heapsort
120algorithm,
121a variant of selection sorting; in particular, see D.E. Knuth's Algorithm H.
122.Fn heapsort
123takes O N lg N worst-case time.
124This implementation of
125.Fn heapsort
126is implemented without recursive function calls.
127.Pp
128The function
129.Fn mergesort
130requires additional memory of size
131.Fa nmemb *
132.Fa size
133bytes; it should be used only when space is not at a premium.
134.Fn mergesort
135is optimized for data with pre-existing order; its worst case
136time is O N lg N; its best case is O N.
137.Pp
138Normally,
139.Fn qsort
140is faster than
141.Fn mergesort ,
142which is faster than
143.Fn heapsort .
144Memory availability and pre-existing order in the data can make this untrue.
145.Sh RETURN VALUES
146The
147.Fn qsort
148function returns no value.
149.Pp
150Upon successful completion,
151.Fn heapsort
152and
153.Fn mergesort
154return 0.
155Otherwise, they return \-1 and the global variable
156.Va errno
157is set to indicate the error.
158.Sh ERRORS
159The
160.Fn heapsort
161and
162.Fn mergesort
163functions succeed unless:
164.Bl -tag -width Er
165.It Bq Er EINVAL
166The
167.Fa size
168argument is zero, or the
169.Fa size
170argument to
171.Fn mergesort
172is less than
173.Dq "sizeof(void *) / 2" .
174.It Bq Er ENOMEM
175.Fn heapsort
176or
177.Fn mergesort
178were unable to allocate memory.
179.El
180.Sh SEE ALSO
181.Xr sort 1 ,
182.Xr radixsort 3
183.Rs
184.%A Hoare, C.A.R.
185.%D 1962
186.%T "Quicksort"
187.%J "The Computer Journal"
188.%V 5:1
189.%P pp. 10-15
190.Re
191.Rs
192.%A Williams, J.W.J
193.%D 1964
194.%T "Heapsort"
195.%J "Communications of the ACM"
196.%V 7:1
197.%P pp. 347\-348
198.Re
199.Rs
200.%A Knuth, D.E.
201.%D 1968
202.%B "The Art of Computer Programming"
203.%V Vol. 3
204.%T "Sorting and Searching"
205.%P pp. 114\-123, 145\-149
206.Re
207.Rs
208.%A McIlroy, P.M.
209.%T "Optimistic Sorting and Information Theoretic Complexity"
210.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
211.%P pp. 467\-464
212.%D January 1993
213.Re
214.Rs
215.%A Bentley, J.L.
216.%A McIlroy, M.D.
217.%T "Engineering a Sort Function"
218.%J "Software \- Practice and Experience"
219.%V Vol. 23(11)
220.%P pp. 1249\-1265
221.%D November 1993
222.Re
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
231.Fn qsort
232function conforms to
233.St -ansiC .
234.Sh HISTORY
235A
236.Fn qsort
237function first appeared in
238.At v3 .
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
new file mode 100644
index 0000000000..f28449fb5b
--- /dev/null
+++ b/src/lib/libc/stdlib/qsort.c
@@ -0,0 +1,162 @@
1/* $OpenBSD: qsort.c,v 1.11 2010/02/08 11:04:07 otto Exp $ */
2/*-
3 * Copyright (c) 1992, 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
31#include <sys/types.h>
32#include <stdlib.h>
33
34static __inline char *med3(char *, char *, char *, int (*)(const void *, const void *));
35static __inline void swapfunc(char *, char *, size_t, int);
36
37#define min(a, b) (a) < (b) ? a : b
38
39/*
40 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
41 */
42#define swapcode(TYPE, parmi, parmj, n) { \
43 size_t i = (n) / sizeof (TYPE); \
44 TYPE *pi = (TYPE *) (parmi); \
45 TYPE *pj = (TYPE *) (parmj); \
46 do { \
47 TYPE t = *pi; \
48 *pi++ = *pj; \
49 *pj++ = t; \
50 } while (--i > 0); \
51}
52
53#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
54 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
55
56static __inline void
57swapfunc(char *a, char *b, size_t n, int swaptype)
58{
59 if (swaptype <= 1)
60 swapcode(long, a, b, n)
61 else
62 swapcode(char, a, b, n)
63}
64
65#define swap(a, b) \
66 if (swaptype == 0) { \
67 long t = *(long *)(a); \
68 *(long *)(a) = *(long *)(b); \
69 *(long *)(b) = t; \
70 } else \
71 swapfunc(a, b, es, swaptype)
72
73#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
74
75static __inline char *
76med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
77{
78 return cmp(a, b) < 0 ?
79 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
80 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
81}
82
83void
84qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
85{
86 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
87 int cmp_result, swaptype, swap_cnt;
88 size_t d, r;
89 char *a = aa;
90
91loop: SWAPINIT(a, es);
92 swap_cnt = 0;
93 if (n < 7) {
94 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
95 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
96 pl -= es)
97 swap(pl, pl - es);
98 return;
99 }
100 pm = (char *)a + (n / 2) * es;
101 if (n > 7) {
102 pl = (char *)a;
103 pn = (char *)a + (n - 1) * es;
104 if (n > 40) {
105 d = (n / 8) * es;
106 pl = med3(pl, pl + d, pl + 2 * d, cmp);
107 pm = med3(pm - d, pm, pm + d, cmp);
108 pn = med3(pn - 2 * d, pn - d, pn, cmp);
109 }
110 pm = med3(pl, pm, pn, cmp);
111 }
112 swap(a, pm);
113 pa = pb = (char *)a + es;
114
115 pc = pd = (char *)a + (n - 1) * es;
116 for (;;) {
117 while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
118 if (cmp_result == 0) {
119 swap_cnt = 1;
120 swap(pa, pb);
121 pa += es;
122 }
123 pb += es;
124 }
125 while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
126 if (cmp_result == 0) {
127 swap_cnt = 1;
128 swap(pc, pd);
129 pd -= es;
130 }
131 pc -= es;
132 }
133 if (pb > pc)
134 break;
135 swap(pb, pc);
136 swap_cnt = 1;
137 pb += es;
138 pc -= es;
139 }
140 if (swap_cnt == 0) { /* Switch to insertion sort */
141 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
142 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
143 pl -= es)
144 swap(pl, pl - es);
145 return;
146 }
147
148 pn = (char *)a + n * es;
149 r = min(pa - (char *)a, pb - pa);
150 vecswap(a, pb - r, r);
151 r = min(pd - pc, pn - pd - es);
152 vecswap(pb, pn - r, r);
153 if ((r = pb - pa) > es)
154 qsort(a, r / es, es, cmp);
155 if ((r = pd - pc) > es) {
156 /* Iterate rather than recurse to save stack space */
157 a = pn - r;
158 n = r / es;
159 goto loop;
160 }
161/* qsort(pn - r, r / es, es, cmp);*/
162}
diff --git a/src/lib/libc/stdlib/radixsort.3 b/src/lib/libc/stdlib/radixsort.3
new file mode 100644
index 0000000000..e62f760270
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,155 @@
1.\" Copyright (c) 1990, 1991, 1993
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $OpenBSD: radixsort.3,v 1.12 2013/06/05 03:39:23 tedu Exp $
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt RADIXSORT 3
32.Os
33.Sh NAME
34.Nm radixsort ,
35.Nm sradixsort
36.Nd radix sort
37.Sh SYNOPSIS
38.In limits.h
39.In stdlib.h
40.Ft int
41.Fn radixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
42.Ft int
43.Fn sradixsort "const u_char **base" "int nmemb" "const u_char *table" "u_int endbyte"
44.Sh DESCRIPTION
45The
46.Fn radixsort
47and
48.Fn sradixsort
49functions are implementations of radix sort.
50.Pp
51These functions sort an array of
52.Fa nmemb
53pointers to byte strings.
54The initial member is referenced by
55.Fa base .
56The byte strings may contain any values; the end of each string
57is denoted by the user-specified value
58.Fa endbyte .
59.Pp
60Applications may specify a sort order by providing the
61.Fa table
62argument.
63If non-null,
64.Fa table
65must reference an array of
66.Dv UCHAR_MAX
67+ 1 bytes which contains the sort weight of each possible byte value.
68The end-of-string byte must have a sort weight of 0 or 255
69(for sorting in reverse order).
70More than one byte may have the same sort weight.
71The
72.Fa table
73argument is useful for applications which wish to sort different characters
74equally; for example, providing a table with the same weights
75for A\-Z as for a\-z will result in a case-insensitive sort.
76If
77.Fa table
78is
79.Dv NULL ,
80the contents of the array are sorted in ascending order according to the
81.Tn ASCII
82order of the byte strings they reference and
83.Fa endbyte
84has a sorting weight of 0.
85.Pp
86The
87.Fn sradixsort
88function is stable; that is, if two elements compare as equal, their
89order in the sorted array is unchanged.
90The
91.Fn sradixsort
92function uses additional memory sufficient to hold
93.Fa nmemb
94pointers.
95.Pp
96The
97.Fn radixsort
98function is not stable, but uses no additional memory.
99.Pp
100These functions are variants of most-significant-byte radix sorting; in
101particular, see D.E. Knuth's Algorithm R and section 5.2.5, exercise 10.
102They take linear time relative to the number of bytes in the strings.
103.Sh RETURN VALUES
104Upon successful completion 0 is returned.
105Otherwise, \-1 is returned and the global variable
106.Va errno
107is set to indicate the error.
108.Sh ERRORS
109.Bl -tag -width Er
110.It Bq Er EINVAL
111The value of the
112.Fa endbyte
113element of
114.Fa table
115is not 0 or 255.
116.El
117.Pp
118Additionally, the
119.Fn sradixsort
120function may fail and set
121.Va errno
122for any of the errors specified for the library routine
123.Xr malloc 3 .
124.Sh SEE ALSO
125.Xr sort 1 ,
126.Xr qsort 3
127.Rs
128.%A Knuth, D.E.
129.%D 1968
130.%B "The Art of Computer Programming"
131.%T "Sorting and Searching"
132.%V Vol. 3
133.%P pp. 170-178
134.Re
135.Rs
136.%A Paige, R.
137.%D 1987
138.%T "Three Partition Refinement Algorithms"
139.%J "SIAM J. Comput."
140.%V Vol. 16
141.%N No. 6
142.Re
143.Rs
144.%A McIlroy, P.
145.%D 1993
146.%B "Engineering Radix Sort"
147.%T "Computing Systems"
148.%V Vol. 6:1
149.%P pp. 5-27
150.Re
151.Sh HISTORY
152The
153.Fn radixsort
154function first appeared in
155.Bx 4.4 .
diff --git a/src/lib/libc/stdlib/radixsort.c b/src/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000000..49d03b52d5
--- /dev/null
+++ b/src/lib/libc/stdlib/radixsort.c
@@ -0,0 +1,294 @@
1/* $OpenBSD: radixsort.c,v 1.9 2007/09/02 15:19:17 deraadt Exp $ */
2/*-
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Peter McIlroy and by Dan Bernstein at New York University,
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the 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/*
35 * Radixsort routines.
36 *
37 * Program r_sort_a() is unstable but uses O(logN) extra memory for a stack.
38 * Use radixsort(a, n, trace, endchar) for this case.
39 *
40 * For stable sorting (using N extra pointers) use sradixsort(), which calls
41 * r_sort_b().
42 *
43 * For a description of this code, see D. McIlroy, P. McIlroy, K. Bostic,
44 * "Engineering Radix Sort".
45 */
46
47#include <sys/types.h>
48#include <stdlib.h>
49#include <errno.h>
50
51typedef struct {
52 const u_char **sa;
53 int sn, si;
54} stack;
55
56static __inline void simplesort
57(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);
59static void r_sort_b(const u_char **,
60 const u_char **, int, int, const u_char *, u_int);
61
62#define THRESHOLD 20 /* Divert to simplesort(). */
63#define SIZE 512 /* Default stack size. */
64
65#define SETUP { \
66 if (tab == NULL) { \
67 tr = tr0; \
68 for (c = 0; c < endch; c++) \
69 tr0[c] = c + 1; \
70 tr0[c] = 0; \
71 for (c++; c < 256; c++) \
72 tr0[c] = c; \
73 endch = 0; \
74 } else { \
75 endch = tab[endch]; \
76 tr = tab; \
77 if (endch != 0 && endch != 255) { \
78 errno = EINVAL; \
79 return (-1); \
80 } \
81 } \
82}
83
84int
85radixsort(const u_char **a, int n, const u_char *tab, u_int endch)
86{
87 const u_char *tr;
88 int c;
89 u_char tr0[256];
90
91 SETUP;
92 r_sort_a(a, n, 0, tr, endch);
93 return (0);
94}
95
96int
97sradixsort(const u_char **a, int n, const u_char *tab, u_int endch)
98{
99 const u_char *tr, **ta;
100 int c;
101 u_char tr0[256];
102
103 SETUP;
104 if (n < THRESHOLD)
105 simplesort(a, n, 0, tr, endch);
106 else {
107 if ((ta = calloc(n, sizeof(a))) == NULL)
108 return (-1);
109 r_sort_b(a, ta, n, 0, tr, endch);
110 free(ta);
111 }
112 return (0);
113}
114
115#define empty(s) (s >= sp)
116#define pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
117#define push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
118#define swap(a, b, t) t = a, a = b, b = t
119
120/* Unstable, in-place sort. */
121void
122r_sort_a(const u_char **a, int n, int i, const u_char *tr, u_int endch)
123{
124 static int count[256], nc, bmin;
125 int c;
126 const u_char **ak, *r;
127 stack s[SIZE], *sp, *sp0, *sp1, temp;
128 int *cp, bigc;
129 const u_char **an, *t, **aj, **top[256];
130
131 /* Set up stack. */
132 sp = s;
133 push(a, n, i);
134 while (!empty(s)) {
135 pop(a, n, i);
136 if (n < THRESHOLD) {
137 simplesort(a, n, i, tr, endch);
138 continue;
139 }
140 an = a + n;
141
142 /* Make character histogram. */
143 if (nc == 0) {
144 bmin = 255; /* First occupied bin, excluding eos. */
145 for (ak = a; ak < an;) {
146 c = tr[(*ak++)[i]];
147 if (++count[c] == 1 && c != endch) {
148 if (c < bmin)
149 bmin = c;
150 nc++;
151 }
152 }
153 if (sp + nc > s + SIZE) { /* Get more stack. */
154 r_sort_a(a, n, i, tr, endch);
155 continue;
156 }
157 }
158
159 /*
160 * Set top[]; push incompletely sorted bins onto stack.
161 * top[] = pointers to last out-of-place element in bins.
162 * count[] = counts of elements in bins.
163 * Before permuting: top[c-1] + count[c] = top[c];
164 * during deal: top[c] counts down to top[c-1].
165 */
166 sp0 = sp1 = sp; /* Stack position of biggest bin. */
167 bigc = 2; /* Size of biggest bin. */
168 if (endch == 0) /* Special case: set top[eos]. */
169 top[0] = ak = a + count[0];
170 else {
171 ak = a;
172 top[255] = an;
173 }
174 for (cp = count + bmin; nc > 0; cp++) {
175 while (*cp == 0) /* Find next non-empty pile. */
176 cp++;
177 if (*cp > 1) {
178 if (*cp > bigc) {
179 bigc = *cp;
180 sp1 = sp;
181 }
182 push(ak, *cp, i+1);
183 }
184 top[cp-count] = ak += *cp;
185 nc--;
186 }
187 swap(*sp0, *sp1, temp); /* Play it safe -- biggest bin last. */
188
189 /*
190 * Permute misplacements home. Already home: everything
191 * before aj, and in bin[c], items from top[c] on.
192 * Inner loop:
193 * r = next element to put in place;
194 * ak = top[r[i]] = location to put the next element.
195 * aj = bottom of 1st disordered bin.
196 * Outer loop:
197 * Once the 1st disordered bin is done, ie. aj >= ak,
198 * aj<-aj + count[c] connects the bins in a linked list;
199 * reset count[c].
200 */
201 for (aj = a; aj < an; *aj = r, aj += count[c], count[c] = 0)
202 for (r = *aj; aj < (ak = --top[c = tr[r[i]]]);)
203 swap(*ak, r, t);
204 }
205}
206
207/* Stable sort, requiring additional memory. */
208void
209r_sort_b(const u_char **a, const u_char **ta, int n, int i, const u_char *tr,
210 u_int endch)
211{
212 static int count[256], nc, bmin;
213 int c;
214 const u_char **ak, **ai;
215 stack s[512], *sp, *sp0, *sp1, temp;
216 const u_char **top[256];
217 int *cp, bigc;
218
219 sp = s;
220 push(a, n, i);
221 while (!empty(s)) {
222 pop(a, n, i);
223 if (n < THRESHOLD) {
224 simplesort(a, n, i, tr, endch);
225 continue;
226 }
227
228 if (nc == 0) {
229 bmin = 255;
230 for (ak = a + n; --ak >= a;) {
231 c = tr[(*ak)[i]];
232 if (++count[c] == 1 && c != endch) {
233 if (c < bmin)
234 bmin = c;
235 nc++;
236 }
237 }
238 if (sp + nc > s + SIZE) {
239 r_sort_b(a, ta, n, i, tr, endch);
240 continue;
241 }
242 }
243
244 sp0 = sp1 = sp;
245 bigc = 2;
246 if (endch == 0) {
247 top[0] = ak = a + count[0];
248 count[0] = 0;
249 } else {
250 ak = a;
251 top[255] = a + n;
252 count[255] = 0;
253 }
254 for (cp = count + bmin; nc > 0; cp++) {
255 while (*cp == 0)
256 cp++;
257 if ((c = *cp) > 1) {
258 if (c > bigc) {
259 bigc = c;
260 sp1 = sp;
261 }
262 push(ak, c, i+1);
263 }
264 top[cp-count] = ak += c;
265 *cp = 0; /* Reset count[]. */
266 nc--;
267 }
268 swap(*sp0, *sp1, temp);
269
270 for (ak = ta + n, ai = a+n; ak > ta;) /* Copy to temp. */
271 *--ak = *--ai;
272 for (ak = ta+n; --ak >= ta;) /* Deal to piles. */
273 *--top[tr[(*ak)[i]]] = *ak;
274 }
275}
276
277static __inline void
278simplesort(const u_char **a, int n, int b, const u_char *tr, u_int endch)
279 /* insertion sort */
280{
281 u_char ch;
282 const u_char **ak, **ai, *s, *t;
283
284 for (ak = a+1; --n >= 1; ak++)
285 for (ai = ak; ai > a; ai--) {
286 for (s = ai[0] + b, t = ai[-1] + b;
287 (ch = tr[*s]) != endch; s++, t++)
288 if (ch != tr[*t])
289 break;
290 if (ch >= tr[*t])
291 break;
292 swap(ai[0], ai[-1], s);
293 }
294}
diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3
new file mode 100644
index 0000000000..75395976f8
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.3
@@ -0,0 +1,105 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: rand.3,v 1.15 2014/04/07 17:57:56 schwarze Exp $
33.\"
34.Dd $Mdocdate: April 7 2014 $
35.Dt RAND 3
36.Os
37.Sh NAME
38.Nm rand ,
39.Nm rand_r ,
40.Nm srand
41.Nd bad random number generator
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft void
45.Fn srand "unsigned int seed"
46.Ft int
47.Fn rand void
48.Ft int
49.Fn rand_r "unsigned int *seed"
50.Sh DESCRIPTION
51.Bf -symbolic
52These interfaces are obsoleted by
53.Xr random 3 .
54.Ef
55.Pp
56The
57.Fn rand
58function computes a sequence of pseudo-random integers in the range
59of 0 to
60.Dv RAND_MAX
61(as defined by the header file
62.In stdlib.h ) .
63.Pp
64The
65.Fn srand
66function sets its argument as the seed for a new sequence of
67pseudo-random numbers to be returned by
68.Fn rand .
69These sequences are repeatable by calling
70.Fn srand
71with the same seed value.
72.Pp
73If no seed value is provided, the functions are automatically
74seeded with a value of 1.
75.Pp
76The
77.Fn rand_r
78is a thread-safe version of
79.Fn rand .
80Storage for the seed must be provided through the
81.Fa seed
82argument, and needs to have been initialized by the caller.
83.Sh SEE ALSO
84.Xr arc4random 3 ,
85.Xr rand48 3 ,
86.Xr random 3
87.Sh STANDARDS
88The
89.Fn rand
90and
91.Fn srand
92functions conform to
93.St -ansiC .
94.Pp
95The
96.Fn rand_r
97function conforms to
98.St -p1003.1-2008 .
99.Sh HISTORY
100The functions
101.Fn rand
102and
103.Fn srand
104first appeared in
105.At v3 .
diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000000..6860dd4f71
--- /dev/null
+++ b/src/lib/libc/stdlib/rand.c
@@ -0,0 +1,67 @@
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/types.h>
31#include <stdlib.h>
32
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}
41
42#if defined(APIWARN)
43__warn_references(rand_r,
44 "warning: rand_r() isn't random; consider using arc4random()");
45#endif
46
47int
48rand(void)
49{
50 return (rand_r(&next));
51}
52
53#if defined(APIWARN)
54__warn_references(rand,
55 "warning: rand() isn't random; consider using arc4random()");
56#endif
57
58void
59srand(u_int seed)
60{
61 next = seed;
62}
63
64#if defined(APIWARN)
65__warn_references(srand,
66 "warning: srand() seed choices are invariably poor");
67#endif
diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3
new file mode 100644
index 0000000000..8b7c572fb4
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.3
@@ -0,0 +1,179 @@
1.\" Copyright (c) 1993 Martin Birgmeier
2.\" All rights reserved.
3.\"
4.\" You may redistribute unmodified or modified versions of this source
5.\" code provided that the above copyright notice and this and the
6.\" following conditions are retained.
7.\"
8.\" This software is provided ``as is'', and comes with no warranties
9.\" of any kind. I shall in no event be liable for anything that happens
10.\" to anyone/anything when using this software.
11.\"
12.\" $OpenBSD: rand48.3,v 1.14 2014/01/21 23:25:03 deraadt Exp $
13.\"
14.Dd $Mdocdate: January 21 2014 $
15.Dt RAND48 3
16.Os
17.Sh NAME
18.Nm drand48 ,
19.Nm erand48 ,
20.Nm lrand48 ,
21.Nm nrand48 ,
22.Nm mrand48 ,
23.Nm jrand48 ,
24.Nm srand48 ,
25.Nm seed48 ,
26.Nm lcong48
27.Nd pseudo-random number generators and initialization routines
28.Sh SYNOPSIS
29.In stdlib.h
30.Ft double
31.Fn drand48 void
32.Ft double
33.Fn erand48 "unsigned short xseed[3]"
34.Ft long
35.Fn lrand48 void
36.Ft long
37.Fn nrand48 "unsigned short xseed[3]"
38.Ft long
39.Fn mrand48 void
40.Ft long
41.Fn jrand48 "unsigned short xseed[3]"
42.Ft void
43.Fn srand48 "long seed"
44.Ft "unsigned short *"
45.Fn seed48 "unsigned short xseed[3]"
46.Ft void
47.Fn lcong48 "unsigned short p[7]"
48.Sh DESCRIPTION
49The
50.Fn rand48
51family of functions generates pseudo-random numbers using a linear
52congruential algorithm working on integers 48 bits in size.
53The particular formula employed is
54r(n+1) = (a * r(n) + c) mod m
55where the default values are
56for the multiplicand a = 0xfdeece66d = 25214903917 and
57the addend c = 0xb = 11.
58The modulus is always fixed at m = 2 ** 48.
59r(n) is called the seed of the random number generator.
60.Pp
61For all the six generator routines described next, the first
62computational step is to perform a single iteration of the algorithm.
63.Pp
64.Fn drand48
65and
66.Fn erand48
67return values of type double.
68The full 48 bits of r(n+1) are
69loaded into the mantissa of the returned value, with the exponent set
70such that the values produced lie in the interval [0.0, 1.0].
71.Pp
72.Fn lrand48
73and
74.Fn nrand48
75return values of type long in the range
76[0, 2**31-1].
77The high-order (31) bits of
78r(n+1) are loaded into the lower bits of the returned value, with
79the topmost (sign) bit set to zero.
80.Pp
81.Fn mrand48
82and
83.Fn jrand48
84return values of type long in the range
85[-2**31, 2**31-1].
86The high-order (32) bits of r(n+1) are loaded into the returned value.
87.Pp
88.Fn drand48 ,
89.Fn lrand48 ,
90and
91.Fn mrand48
92use an internal buffer to store r(n).
93For these functions
94the initial value of r(0) = 0x1234abcd330e = 20017429951246.
95.Pp
96On the other hand,
97.Fn erand48 ,
98.Fn nrand48 ,
99and
100.Fn jrand48
101use a user-supplied buffer to store the seed r(n),
102which consists of an array of 3 shorts, where the zeroth member
103holds the least significant bits.
104.Pp
105All functions share the same multiplicand and addend.
106.Pp
107.Fn srand48
108is used to initialize the internal buffer r(n) of
109.Fn drand48 ,
110.Fn lrand48 ,
111and
112.Fn mrand48
113such that the 32 bits of the seed value are copied into the upper 32 bits
114of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e.
115Additionally, the constant multiplicand and addend of the algorithm are
116reset to the default values given above.
117.Pp
118.Fn seed48
119also initializes the internal buffer r(n) of
120.Fn drand48 ,
121.Fn lrand48 ,
122and
123.Fn mrand48 ,
124but here all 48 bits of the seed can be specified in an array of 3 shorts,
125where the zeroth member specifies the lowest bits.
126Again, the constant multiplicand and addend of the algorithm are
127reset to the default values given above.
128.Fn seed48
129returns a pointer to an array of 3 shorts which contains the old seed.
130This array is statically allocated, so its contents are lost after
131each new call to
132.Fn seed48 .
133.Pp
134Finally,
135.Fn lcong48
136allows full control over the multiplicand and addend used in
137.Fn drand48 ,
138.Fn erand48 ,
139.Fn lrand48 ,
140.Fn nrand48 ,
141.Fn mrand48 ,
142and
143.Fn jrand48 ,
144and the seed used in
145.Fn drand48 ,
146.Fn lrand48 ,
147and
148.Fn mrand48 .
149An array of 7 shorts is passed as parameter; the first three shorts are
150used to initialize the seed; the second three are used to initialize the
151multiplicand; and the last short is used to initialize the addend.
152It is thus not possible to use values greater than 0xffff as the addend.
153.Pp
154Note that all three methods of seeding the random number generator
155always also set the multiplicand and addend for any of the six
156generator calls.
157.Pp
158For a more powerful random number generator, see
159.Xr arc4random 3 .
160.Sh SEE ALSO
161.Xr arc4random 3 ,
162.Xr rand 3 ,
163.Xr random 3
164.Sh STANDARDS
165The
166.Fn drand48 ,
167.Fn erand48 ,
168.Fn jrand48 ,
169.Fn lcong48 ,
170.Fn lrand48 ,
171.Fn mrand48 ,
172.Fn nrand48 ,
173.Fn seed48 ,
174and
175.Fn srand48
176functions conform to
177.St -p1003.1-2008 .
178.Sh AUTHORS
179Martin Birgmeier
diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h
new file mode 100644
index 0000000000..afa49f65f3
--- /dev/null
+++ b/src/lib/libc/stdlib/rand48.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 1993 Martin Birgmeier
3 * All rights reserved.
4 *
5 * You may redistribute unmodified or modified versions of this source
6 * code provided that the above copyright notice and this and the
7 * following conditions are retained.
8 *
9 * This software is provided ``as is'', and comes with no warranties
10 * of any kind. I shall in no event be liable for anything that happens
11 * to anyone/anything when using this software.
12 *
13 * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
14 */
15
16#ifndef _RAND48_H_
17#define _RAND48_H_
18
19#include <math.h>
20#include <stdlib.h>
21
22void __dorand48(unsigned short[3]);
23
24#define RAND48_SEED_0 (0x330e)
25#define RAND48_SEED_1 (0xabcd)
26#define RAND48_SEED_2 (0x1234)
27#define RAND48_MULT_0 (0xe66d)
28#define RAND48_MULT_1 (0xdeec)
29#define RAND48_MULT_2 (0x0005)
30#define RAND48_ADD (0x000b)
31
32#endif /* _RAND48_H_ */
diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3
new file mode 100644
index 0000000000..fdb78848d8
--- /dev/null
+++ b/src/lib/libc/stdlib/random.3
@@ -0,0 +1,185 @@
1.\" Copyright (c) 1983, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $OpenBSD: random.3,v 1.21 2013/06/05 03:39:23 tedu Exp $
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt RANDOM 3
32.Os
33.Sh NAME
34.Nm random ,
35.Nm srandom ,
36.Nm srandomdev ,
37.Nm initstate ,
38.Nm setstate
39.Nd better random number generator; routines for changing generators
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft long
43.Fn random void
44.Ft void
45.Fn srandom "unsigned int seed"
46.Ft void
47.Fn srandomdev void
48.Ft char *
49.Fn initstate "unsigned int seed" "char *state" "size_t n"
50.Ft char *
51.Fn setstate "char *state"
52.Sh DESCRIPTION
53The
54.Fn random
55function uses a non-linear additive feedback random number generator employing
56a default table of size 31 long integers to return successive pseudo-random
57numbers in the range from 0 to (2**31)\-1.
58The period of this random number generator is very large, approximately
5916*((2**31)\-1).
60.Pp
61The
62.Fn random
63and
64.Fn srandom
65functions have (almost) the same calling sequence and initialization
66properties as
67.Xr rand 3 Ns / Ns Xr srand 3 .
68The difference is that
69.Xr rand
70produces a much less random sequence \(em in fact, the low dozen bits
71generated by rand go through a cyclic pattern.
72All the bits generated by
73.Fn random
74are usable.
75For example,
76.Sq Li random()&01
77will produce a random binary
78value.
79.Pp
80Like
81.Xr rand 3 ,
82.Fn random
83will by default produce a sequence of numbers that can be duplicated
84by calling
85.Fn srandom
86with
87.Ql 1
88as the seed.
89.Pp
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
103.Fn initstate
104routine allows a state array, passed in as an argument, to be initialized
105for future use.
106The size of the state array (in bytes) is used by
107.Fn initstate
108to decide how sophisticated a random number generator it should use \(em the
109more state, the better the random numbers will be.
110(Current "optimal" values for the amount of state information are
1118, 32, 64, 128, and 256 bytes; other amounts will be rounded down to
112the nearest known amount.
113Using less than 8 bytes will cause an error.)
114The seed for the initialization (which specifies a starting point for
115the random number sequence, and provides for restarting at the same
116point) is also an argument.
117The
118.Fn initstate
119function returns a pointer to the previous state information array.
120.Pp
121Once a state has been initialized, the
122.Fn setstate
123routine provides for rapid switching between states.
124The
125.Fn setstate
126function returns a pointer to the previous state array; its
127argument state array is used for further random number generation
128until the next call to
129.Fn initstate
130or
131.Fn setstate .
132.Pp
133Once a state array has been initialized, it may be restarted at a
134different point either by calling
135.Fn initstate
136(with the desired seed, the state array, and its size) or by calling
137both
138.Fn setstate
139(with the state array) and
140.Fn srandom
141(with the desired seed).
142The advantage of calling both
143.Fn setstate
144and
145.Fn srandom
146is that the size of the state array does not have to be remembered after
147it is initialized.
148.Pp
149With 256 bytes of state information, the period of the random number
150generator is greater than 2**69
151which should be sufficient for most purposes.
152.Sh DIAGNOSTICS
153If
154.Fn initstate
155is called with less than 8 bytes of state information, or if
156.Fn setstate
157detects that the state information has been garbled, error
158messages are printed on the standard error output.
159.Sh SEE ALSO
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.
177.Sh HISTORY
178These
179functions appeared in
180.Bx 4.2 .
181.Sh AUTHORS
182.An Earl T. Cohen
183.Sh BUGS
184About 2/3 the speed of
185.Xr rand 3 .
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
new file mode 100644
index 0000000000..00edf2dca1
--- /dev/null
+++ b/src/lib/libc/stdlib/random.c
@@ -0,0 +1,446 @@
1/* $OpenBSD: random.c,v 1.19 2013/08/01 19:42:08 kettenis Exp $ */
2/*
3 * Copyright (c) 1983 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/param.h>
32#include <sys/sysctl.h>
33#include <sys/time.h>
34#include <fcntl.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <unistd.h>
38
39#include "thread_private.h"
40
41/*
42 * random.c:
43 *
44 * An improved random number generation package. In addition to the standard
45 * rand()/srand() like interface, this package also has a special state info
46 * interface. The initstate() routine is called with a seed, an array of
47 * bytes, and a count of how many bytes are being passed in; this array is
48 * then initialized to contain information for random number generation with
49 * that much state information. Good sizes for the amount of state
50 * information are 32, 64, 128, and 256 bytes. The state can be switched by
51 * calling the setstate() routine with the same array as was initiallized
52 * with initstate(). By default, the package runs with 128 bytes of state
53 * information and generates far better random numbers than a linear
54 * congruential generator. If the amount of state information is less than
55 * 32 bytes, a simple linear congruential R.N.G. is used.
56 *
57 * Internally, the state information is treated as an array of int32_t; the
58 * zeroeth element of the array is the type of R.N.G. being used (small
59 * integer); the remainder of the array is the state information for the
60 * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of
61 * state information, which will allow a degree seven polynomial. (Note:
62 * the zeroeth word of state information also has some other information
63 * stored in it -- see setstate() for details).
64 *
65 * The random number generation technique is a linear feedback shift register
66 * approach, employing trinomials (since there are fewer terms to sum up that
67 * way). In this approach, the least significant bit of all the numbers in
68 * the state table will act as a linear feedback shift register, and will
69 * have period 2^deg - 1 (where deg is the degree of the polynomial being
70 * used, assuming that the polynomial is irreducible and primitive). The
71 * higher order bits will have longer periods, since their values are also
72 * influenced by pseudo-random carries out of the lower bits. The total
73 * period of the generator is approximately deg*(2**deg - 1); thus doubling
74 * the amount of state information has a vast influence on the period of the
75 * generator. Note: the deg*(2**deg - 1) is an approximation only good for
76 * large deg, when the period of the shift register is the dominant factor.
77 * With deg equal to seven, the period is actually much longer than the
78 * 7*(2**7 - 1) predicted by this formula.
79 */
80
81/*
82 * For each of the currently supported random number generators, we have a
83 * break value on the amount of state information (you need at least this
84 * many bytes of state info to support this random number generator), a degree
85 * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
86 * the separation between the two lower order coefficients of the trinomial.
87 */
88#define TYPE_0 0 /* linear congruential */
89#define BREAK_0 8
90#define DEG_0 0
91#define SEP_0 0
92
93#define TYPE_1 1 /* x**7 + x**3 + 1 */
94#define BREAK_1 32
95#define DEG_1 7
96#define SEP_1 3
97
98#define TYPE_2 2 /* x**15 + x + 1 */
99#define BREAK_2 64
100#define DEG_2 15
101#define SEP_2 1
102
103#define TYPE_3 3 /* x**31 + x**3 + 1 */
104#define BREAK_3 128
105#define DEG_3 31
106#define SEP_3 3
107
108#define TYPE_4 4 /* x**63 + x + 1 */
109#define BREAK_4 256
110#define DEG_4 63
111#define SEP_4 1
112
113/*
114 * Array versions of the above information to make code run faster --
115 * relies on fact that TYPE_i == i.
116 */
117#define MAX_TYPES 5 /* max number of types above */
118
119static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
120static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
121
122/*
123 * Initially, everything is set up as if from:
124 *
125 * initstate(1, &randtbl, 128);
126 *
127 * Note that this initialization takes advantage of the fact that srandom()
128 * advances the front and rear pointers 10*rand_deg times, and hence the
129 * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
130 * element of the state information, which contains info about the current
131 * position of the rear pointer is just
132 *
133 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
134 */
135
136static int32_t randtbl[DEG_3 + 1] = {
137 TYPE_3,
138 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
139 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
140 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
141 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
142 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
143 0xf3bec5da,
144};
145
146/*
147 * fptr and rptr are two pointers into the state info, a front and a rear
148 * pointer. These two pointers are always rand_sep places aparts, as they
149 * cycle cyclically through the state information. (Yes, this does mean we
150 * could get away with just one pointer, but the code for random() is more
151 * efficient this way). The pointers are left positioned as they would be
152 * from the call
153 *
154 * initstate(1, randtbl, 128);
155 *
156 * (The position of the rear pointer, rptr, is really 0 (as explained above
157 * in the initialization of randtbl) because the state table pointer is set
158 * to point to randtbl[1] (as explained below).
159 */
160static int32_t *fptr = &randtbl[SEP_3 + 1];
161static int32_t *rptr = &randtbl[1];
162
163/*
164 * The following things are the pointer to the state information table, the
165 * type of the current generator, the degree of the current polynomial being
166 * used, and the separation between the two pointers. Note that for efficiency
167 * of random(), we remember the first location of the state information, not
168 * the zeroeth. Hence it is valid to access state[-1], which is used to
169 * store the type of the R.N.G. Also, we remember the last location, since
170 * this is more efficient than indexing every time to find the address of
171 * the last element to see if the front and rear pointers have wrapped.
172 */
173static int32_t *state = &randtbl[1];
174static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3;
176static int rand_deg = DEG_3;
177static int rand_sep = SEP_3;
178
179_THREAD_PRIVATE_MUTEX(random);
180static long random_l(void);
181
182#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random)
183#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random)
184
185/*
186 * srandom:
187 *
188 * Initialize the random number generator based on the given seed. If the
189 * type is the trivial no-state-information type, just remember the seed.
190 * Otherwise, initializes state[] based on the given "seed" via a linear
191 * congruential generator. Then, the pointers are set to known locations
192 * that are exactly rand_sep places apart. Lastly, it cycles the state
193 * information a given number of times to get rid of any initial dependencies
194 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
195 * for default usage relies on values produced by this routine.
196 */
197static void
198srandom_l(unsigned int x)
199{
200 int i;
201 int32_t test;
202 div_t val;
203
204 if (rand_type == TYPE_0)
205 state[0] = x;
206 else {
207 /* A seed of 0 would result in state[] always being zero. */
208 state[0] = x ? x : 1;
209 for (i = 1; i < rand_deg; i++) {
210 /*
211 * Implement the following, without overflowing 31 bits:
212 *
213 * state[i] = (16807 * state[i - 1]) % 2147483647;
214 *
215 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
216 */
217 val = div(state[i-1], 127773);
218 test = 16807 * val.rem - 2836 * val.quot;
219 state[i] = test + (test < 0 ? 2147483647 : 0);
220 }
221 fptr = &state[rand_sep];
222 rptr = &state[0];
223 for (i = 0; i < 10 * rand_deg; i++)
224 (void)random_l();
225 }
226}
227
228void
229srandom(unsigned int x)
230{
231 LOCK();
232 srandom_l(x);
233 UNLOCK();
234}
235
236#if defined(APIWARN)
237__warn_references(srandom,
238 "warning: srandom() seed choices are invariably poor");
239#endif
240
241/*
242 * srandomdev:
243 *
244 * Many programs choose the seed value in a totally predictable manner.
245 * This often causes problems. We seed the generator using random
246 * data from the kernel.
247 * Note that this particular seeding procedure can generate states
248 * which are impossible to reproduce by calling srandom() with any
249 * value, since the succeeding terms in the state buffer are no longer
250 * derived from the LC algorithm applied to a fixed seed.
251 */
252void
253srandomdev(void)
254{
255 int mib[2];
256 size_t len;
257
258 LOCK();
259 if (rand_type == TYPE_0)
260 len = sizeof(state[0]);
261 else
262 len = rand_deg * sizeof(state[0]);
263
264 mib[0] = CTL_KERN;
265 mib[1] = KERN_ARND;
266 sysctl(mib, 2, state, &len, NULL, 0);
267
268 if (rand_type != TYPE_0) {
269 fptr = &state[rand_sep];
270 rptr = &state[0];
271 }
272 UNLOCK();
273}
274
275#if defined(APIWARN)
276__warn_references(srandomdev,
277 "warning: srandomdev() usage; consider switching to arc4random()");
278#endif
279
280/*
281 * initstate:
282 *
283 * Initialize the state information in the given array of n bytes for future
284 * random number generation. Based on the number of bytes we are given, and
285 * the break values for the different R.N.G.'s, we choose the best (largest)
286 * one we can and set things up for it. srandom() is then called to
287 * initialize the state information.
288 *
289 * Note that on return from srandom(), we set state[-1] to be the type
290 * multiplexed with the current value of the rear pointer; this is so
291 * successive calls to initstate() won't lose this information and will be
292 * able to restart with setstate().
293 *
294 * Note: the first thing we do is save the current state, if any, just like
295 * setstate() so that it doesn't matter when initstate is called.
296 *
297 * Returns a pointer to the old state.
298 */
299char *
300initstate(u_int seed, char *arg_state, size_t n)
301{
302 char *ostate = (char *)(&state[-1]);
303
304 LOCK();
305 if (rand_type == TYPE_0)
306 state[-1] = rand_type;
307 else
308 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
309 if (n < BREAK_0) {
310 UNLOCK();
311 return(NULL);
312 }
313 if (n < BREAK_1) {
314 rand_type = TYPE_0;
315 rand_deg = DEG_0;
316 rand_sep = SEP_0;
317 } else if (n < BREAK_2) {
318 rand_type = TYPE_1;
319 rand_deg = DEG_1;
320 rand_sep = SEP_1;
321 } else if (n < BREAK_3) {
322 rand_type = TYPE_2;
323 rand_deg = DEG_2;
324 rand_sep = SEP_2;
325 } else if (n < BREAK_4) {
326 rand_type = TYPE_3;
327 rand_deg = DEG_3;
328 rand_sep = SEP_3;
329 } else {
330 rand_type = TYPE_4;
331 rand_deg = DEG_4;
332 rand_sep = SEP_4;
333 }
334 state = &(((int32_t *)arg_state)[1]); /* first location */
335 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
336 srandom_l(seed);
337 if (rand_type == TYPE_0)
338 state[-1] = rand_type;
339 else
340 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
341 UNLOCK();
342 return(ostate);
343}
344
345/*
346 * setstate:
347 *
348 * Restore the state from the given state array.
349 *
350 * Note: it is important that we also remember the locations of the pointers
351 * in the current state information, and restore the locations of the pointers
352 * from the old state information. This is done by multiplexing the pointer
353 * location into the zeroeth word of the state information.
354 *
355 * Note that due to the order in which things are done, it is OK to call
356 * setstate() with the same state as the current state.
357 *
358 * Returns a pointer to the old state information.
359 */
360char *
361setstate(char *arg_state)
362{
363 int32_t *new_state = (int32_t *)arg_state;
364 int32_t type = new_state[0] % MAX_TYPES;
365 int32_t rear = new_state[0] / MAX_TYPES;
366 char *ostate = (char *)(&state[-1]);
367
368 LOCK();
369 if (rand_type == TYPE_0)
370 state[-1] = rand_type;
371 else
372 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
373 switch(type) {
374 case TYPE_0:
375 case TYPE_1:
376 case TYPE_2:
377 case TYPE_3:
378 case TYPE_4:
379 rand_type = type;
380 rand_deg = degrees[type];
381 rand_sep = seps[type];
382 break;
383 default:
384 UNLOCK();
385 return(NULL);
386 }
387 state = &new_state[1];
388 if (rand_type != TYPE_0) {
389 rptr = &state[rear];
390 fptr = &state[(rear + rand_sep) % rand_deg];
391 }
392 end_ptr = &state[rand_deg]; /* set end_ptr too */
393 UNLOCK();
394 return(ostate);
395}
396
397/*
398 * random:
399 *
400 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
401 * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
402 * the same in all the other cases due to all the global variables that have
403 * been set up. The basic operation is to add the number at the rear pointer
404 * into the one at the front pointer. Then both pointers are advanced to
405 * the next location cyclically in the table. The value returned is the sum
406 * generated, reduced to 31 bits by throwing away the "least random" low bit.
407 *
408 * Note: the code takes advantage of the fact that both the front and
409 * rear pointers can't wrap on the same call by not testing the rear
410 * pointer if the front one has wrapped.
411 *
412 * Returns a 31-bit random number.
413 */
414static long
415random_l(void)
416{
417 int32_t i;
418
419 if (rand_type == TYPE_0)
420 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
421 else {
422 *fptr += *rptr;
423 i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
424 if (++fptr >= end_ptr) {
425 fptr = state;
426 ++rptr;
427 } else if (++rptr >= end_ptr)
428 rptr = state;
429 }
430 return((long)i);
431}
432
433long
434random(void)
435{
436 long r;
437 LOCK();
438 r = random_l();
439 UNLOCK();
440 return r;
441}
442
443#if defined(APIWARN)
444__warn_references(random,
445 "warning: random() isn't random; consider using arc4random()");
446#endif
diff --git a/src/lib/libc/stdlib/realpath.3 b/src/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000000..5966b38058
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.3
@@ -0,0 +1,130 @@
1.\" Copyright (c) 1994
2.\" The Regents of the University of California. All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Jan-Simon Pendry.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. 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.\" $OpenBSD: realpath.3,v 1.19 2014/01/20 22:40:06 schwarze Exp $
32.\"
33.Dd $Mdocdate: January 20 2014 $
34.Dt REALPATH 3
35.Os
36.Sh NAME
37.Nm realpath
38.Nd returns the canonicalized absolute pathname
39.Sh SYNOPSIS
40.In limits.h
41.In stdlib.h
42.Ft "char *"
43.Fn realpath "const char *pathname" "char *resolved"
44.Sh DESCRIPTION
45The
46.Fn realpath
47function resolves all symbolic links, extra
48.Dq /
49characters and references to
50.Pa /./
51and
52.Pa /../
53in
54.Fa pathname ,
55and copies the resulting absolute pathname into the memory referenced by
56.Fa resolved .
57The
58.Fa resolved
59argument
60.Em must
61refer to a buffer capable of storing at least
62.Dv PATH_MAX
63characters, or be
64.Dv NULL .
65.Pp
66The
67.Fn realpath
68function will resolve both absolute and relative paths
69and return the absolute pathname corresponding to
70.Fa pathname .
71All but the last component of
72.Fa pathname
73must exist when
74.Fn realpath
75is called.
76.Sh RETURN VALUES
77The
78.Fn realpath
79function returns
80.Fa resolved
81on success.
82If
83.Fa resolved
84is
85.Dv NULL
86and no error occurred, then
87.Fn realpath
88returns a NUL-terminated string in a newly allocated buffer.
89If an error occurs,
90.Fn realpath
91returns
92.Dv NULL
93and the contents of
94.Fa resolved
95are undefined.
96.Sh ERRORS
97The function
98.Fn realpath
99may fail and set the external variable
100.Va errno
101for any of the errors specified for the library functions
102.Xr lstat 2 ,
103.Xr readlink 2 ,
104and
105.Xr getcwd 3 .
106.Sh SEE ALSO
107.Xr readlink 1 ,
108.Xr getcwd 3
109.Sh STANDARDS
110The
111.Fn realpath
112function conforms to
113.St -p1003.1-2008 .
114.Sh HISTORY
115The
116.Fn realpath
117function call first appeared in
118.Bx 4.4 .
119.Sh CAVEATS
120This implementation of
121.Fn realpath
122differs slightly from the Solaris implementation.
123The
124.Bx 4.4
125version always returns absolute pathnames,
126whereas the Solaris implementation will,
127under certain circumstances, return a relative
128.Fa resolved
129when given a relative
130.Fa pathname .
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
new file mode 100644
index 0000000000..e0f9b123b3
--- /dev/null
+++ b/src/lib/libc/stdlib/realpath.c
@@ -0,0 +1,214 @@
1/* $OpenBSD: realpath.c,v 1.16 2013/04/05 12:59:54 kurt Exp $ */
2/*
3 * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
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 names of the authors may not be used to endorse or promote
14 * products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/param.h>
31#include <sys/stat.h>
32
33#include <errno.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37
38/* A slightly modified copy of this file exists in libexec/ld.so */
39
40/*
41 * char *realpath(const char *path, char resolved[PATH_MAX]);
42 *
43 * Find the real name of path, by removing all ".", ".." and symlink
44 * components. Returns (resolved) on success, or (NULL) on failure,
45 * in which case the path which caused trouble is left in (resolved).
46 */
47char *
48realpath(const char *path, char *resolved)
49{
50 struct stat sb;
51 char *p, *q, *s;
52 size_t left_len, resolved_len;
53 unsigned symlinks;
54 int serrno, slen, mem_allocated;
55 char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
56
57 if (path[0] == '\0') {
58 errno = ENOENT;
59 return (NULL);
60 }
61
62 serrno = errno;
63
64 if (resolved == NULL) {
65 resolved = malloc(PATH_MAX);
66 if (resolved == NULL)
67 return (NULL);
68 mem_allocated = 1;
69 } else
70 mem_allocated = 0;
71
72 symlinks = 0;
73 if (path[0] == '/') {
74 resolved[0] = '/';
75 resolved[1] = '\0';
76 if (path[1] == '\0')
77 return (resolved);
78 resolved_len = 1;
79 left_len = strlcpy(left, path + 1, sizeof(left));
80 } else {
81 if (getcwd(resolved, PATH_MAX) == NULL) {
82 if (mem_allocated)
83 free(resolved);
84 else
85 strlcpy(resolved, ".", PATH_MAX);
86 return (NULL);
87 }
88 resolved_len = strlen(resolved);
89 left_len = strlcpy(left, path, sizeof(left));
90 }
91 if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
92 errno = ENAMETOOLONG;
93 goto err;
94 }
95
96 /*
97 * Iterate over path components in `left'.
98 */
99 while (left_len != 0) {
100 /*
101 * Extract the next path component and adjust `left'
102 * and its length.
103 */
104 p = strchr(left, '/');
105 s = p ? p : left + left_len;
106 if (s - left >= sizeof(next_token)) {
107 errno = ENAMETOOLONG;
108 goto err;
109 }
110 memcpy(next_token, left, s - left);
111 next_token[s - left] = '\0';
112 left_len -= s - left;
113 if (p != NULL)
114 memmove(left, s + 1, left_len + 1);
115 if (resolved[resolved_len - 1] != '/') {
116 if (resolved_len + 1 >= PATH_MAX) {
117 errno = ENAMETOOLONG;
118 goto err;
119 }
120 resolved[resolved_len++] = '/';
121 resolved[resolved_len] = '\0';
122 }
123 if (next_token[0] == '\0')
124 continue;
125 else if (strcmp(next_token, ".") == 0)
126 continue;
127 else if (strcmp(next_token, "..") == 0) {
128 /*
129 * Strip the last path component except when we have
130 * single "/"
131 */
132 if (resolved_len > 1) {
133 resolved[resolved_len - 1] = '\0';
134 q = strrchr(resolved, '/') + 1;
135 *q = '\0';
136 resolved_len = q - resolved;
137 }
138 continue;
139 }
140
141 /*
142 * Append the next path component and lstat() it. If
143 * lstat() fails we still can return successfully if
144 * there are no more path components left.
145 */
146 resolved_len = strlcat(resolved, next_token, PATH_MAX);
147 if (resolved_len >= PATH_MAX) {
148 errno = ENAMETOOLONG;
149 goto err;
150 }
151 if (lstat(resolved, &sb) != 0) {
152 if (errno == ENOENT && p == NULL) {
153 errno = serrno;
154 return (resolved);
155 }
156 goto err;
157 }
158 if (S_ISLNK(sb.st_mode)) {
159 if (symlinks++ > MAXSYMLINKS) {
160 errno = ELOOP;
161 goto err;
162 }
163 slen = readlink(resolved, symlink, sizeof(symlink) - 1);
164 if (slen < 0)
165 goto err;
166 symlink[slen] = '\0';
167 if (symlink[0] == '/') {
168 resolved[1] = 0;
169 resolved_len = 1;
170 } else if (resolved_len > 1) {
171 /* Strip the last path component. */
172 resolved[resolved_len - 1] = '\0';
173 q = strrchr(resolved, '/') + 1;
174 *q = '\0';
175 resolved_len = q - resolved;
176 }
177
178 /*
179 * If there are any path components left, then
180 * append them to symlink. The result is placed
181 * in `left'.
182 */
183 if (p != NULL) {
184 if (symlink[slen - 1] != '/') {
185 if (slen + 1 >= sizeof(symlink)) {
186 errno = ENAMETOOLONG;
187 goto err;
188 }
189 symlink[slen] = '/';
190 symlink[slen + 1] = 0;
191 }
192 left_len = strlcat(symlink, left, sizeof(symlink));
193 if (left_len >= sizeof(left)) {
194 errno = ENAMETOOLONG;
195 goto err;
196 }
197 }
198 left_len = strlcpy(left, symlink, sizeof(left));
199 }
200 }
201
202 /*
203 * Remove trailing slash except when the resolved pathname
204 * is a single "/".
205 */
206 if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
207 resolved[resolved_len - 1] = '\0';
208 return (resolved);
209
210err:
211 if (mem_allocated)
212 free(resolved);
213 return (NULL);
214}
diff --git a/src/lib/libc/stdlib/remque.c b/src/lib/libc/stdlib/remque.c
new file mode 100644
index 0000000000..ae249ae053
--- /dev/null
+++ b/src/lib/libc/stdlib/remque.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: remque.c,v 1.2 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1993 John Brezak
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <search.h>
32
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
new file mode 100644
index 0000000000..583262f2d5
--- /dev/null
+++ b/src/lib/libc/stdlib/seed48.c
@@ -0,0 +1,37 @@
1/* $OpenBSD: seed48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18extern unsigned short __rand48_mult[3];
19extern unsigned short __rand48_add;
20
21unsigned short *
22seed48(unsigned short xseed[3])
23{
24 static unsigned short sseed[3];
25
26 sseed[0] = __rand48_seed[0];
27 sseed[1] = __rand48_seed[1];
28 sseed[2] = __rand48_seed[2];
29 __rand48_seed[0] = xseed[0];
30 __rand48_seed[1] = xseed[1];
31 __rand48_seed[2] = xseed[2];
32 __rand48_mult[0] = RAND48_MULT_0;
33 __rand48_mult[1] = RAND48_MULT_1;
34 __rand48_mult[2] = RAND48_MULT_2;
35 __rand48_add = RAND48_ADD;
36 return sseed;
37}
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
new file mode 100644
index 0000000000..9060fdba88
--- /dev/null
+++ b/src/lib/libc/stdlib/setenv.c
@@ -0,0 +1,180 @@
1/* $OpenBSD: setenv.c,v 1.14 2012/09/23 16:08:04 jeremy Exp $ */
2/*
3 * Copyright (c) 1987 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <errno.h>
32#include <stdlib.h>
33#include <string.h>
34
35char *__findenv(const char *name, int len, int *offset);
36
37extern char **environ;
38static char **lastenv; /* last value of environ */
39
40/*
41 * putenv --
42 * Add a name=value string directly to the environmental, replacing
43 * any current value.
44 */
45int
46putenv(char *str)
47{
48 char **P, *cp;
49 size_t cnt;
50 int offset = 0;
51
52 for (cp = str; *cp && *cp != '='; ++cp)
53 ;
54 if (*cp != '=') {
55 errno = EINVAL;
56 return (-1); /* missing `=' in string */
57 }
58
59 if (__findenv(str, (int)(cp - str), &offset) != NULL) {
60 environ[offset++] = str;
61 /* could be set multiple times */
62 while (__findenv(str, (int)(cp - str), &offset)) {
63 for (P = &environ[offset];; ++P)
64 if (!(*P = *(P + 1)))
65 break;
66 }
67 return (0);
68 }
69
70 /* create new slot for string */
71 for (P = environ; *P != NULL; P++)
72 ;
73 cnt = P - environ;
74 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
75 if (!P)
76 return (-1);
77 if (lastenv != environ)
78 memcpy(P, environ, cnt * sizeof(char *));
79 lastenv = environ = P;
80 environ[cnt] = str;
81 environ[cnt + 1] = NULL;
82 return (0);
83}
84
85/*
86 * setenv --
87 * Set the value of the environmental variable "name" to be
88 * "value". If rewrite is set, replace any current value.
89 */
90int
91setenv(const char *name, const char *value, int rewrite)
92{
93 char *C, **P;
94 const char *np;
95 int l_value, offset = 0;
96
97 if (!name || !*name) {
98 errno = EINVAL;
99 return (-1);
100 }
101 for (np = name; *np && *np != '='; ++np)
102 ;
103 if (*np) {
104 errno = EINVAL;
105 return (-1); /* has `=' in name */
106 }
107
108 l_value = strlen(value);
109 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
110 int tmpoff = offset + 1;
111 if (!rewrite)
112 return (0);
113#if 0 /* XXX - existing entry may not be writable */
114 if (strlen(C) >= l_value) { /* old larger; copy over */
115 while ((*C++ = *value++))
116 ;
117 return (0);
118 }
119#endif
120 /* could be set multiple times */
121 while (__findenv(name, (int)(np - name), &tmpoff)) {
122 for (P = &environ[tmpoff];; ++P)
123 if (!(*P = *(P + 1)))
124 break;
125 }
126 } else { /* create new slot */
127 size_t cnt;
128
129 for (P = environ; *P != NULL; P++)
130 ;
131 cnt = P - environ;
132 P = (char **)realloc(lastenv, sizeof(char *) * (cnt + 2));
133 if (!P)
134 return (-1);
135 if (lastenv != environ)
136 memcpy(P, environ, cnt * sizeof(char *));
137 lastenv = environ = P;
138 offset = cnt;
139 environ[cnt + 1] = NULL;
140 }
141 if (!(environ[offset] = /* name + `=' + value */
142 malloc((size_t)((int)(np - name) + l_value + 2))))
143 return (-1);
144 for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
145 ;
146 for (*C++ = '='; (*C++ = *value++); )
147 ;
148 return (0);
149}
150
151/*
152 * unsetenv(name) --
153 * Delete environmental variable "name".
154 */
155int
156unsetenv(const char *name)
157{
158 char **P;
159 const char *np;
160 int offset = 0;
161
162 if (!name || !*name) {
163 errno = EINVAL;
164 return (-1);
165 }
166 for (np = name; *np && *np != '='; ++np)
167 ;
168 if (*np) {
169 errno = EINVAL;
170 return (-1); /* has `=' in name */
171 }
172
173 /* could be set multiple times */
174 while (__findenv(name, (int)(np - name), &offset)) {
175 for (P = &environ[offset];; ++P)
176 if (!(*P = *(P + 1)))
177 break;
178 }
179 return (0);
180}
diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c
new file mode 100644
index 0000000000..f76b6cca86
--- /dev/null
+++ b/src/lib/libc/stdlib/srand48.c
@@ -0,0 +1,31 @@
1/* $OpenBSD: srand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1993 Martin Birgmeier
4 * All rights reserved.
5 *
6 * You may redistribute unmodified or modified versions of this source
7 * code provided that the above copyright notice and this and the
8 * following conditions are retained.
9 *
10 * This software is provided ``as is'', and comes with no warranties
11 * of any kind. I shall in no event be liable for anything that happens
12 * to anyone/anything when using this software.
13 */
14
15#include "rand48.h"
16
17extern unsigned short __rand48_seed[3];
18extern unsigned short __rand48_mult[3];
19extern unsigned short __rand48_add;
20
21void
22srand48(long seed)
23{
24 __rand48_seed[0] = RAND48_SEED_0;
25 __rand48_seed[1] = (unsigned short) seed;
26 __rand48_seed[2] = (unsigned short) (seed >> 16);
27 __rand48_mult[0] = RAND48_MULT_0;
28 __rand48_mult[1] = RAND48_MULT_1;
29 __rand48_mult[2] = RAND48_MULT_2;
30 __rand48_add = RAND48_ADD;
31}
diff --git a/src/lib/libc/stdlib/strtod.3 b/src/lib/libc/stdlib/strtod.3
new file mode 100644
index 0000000000..6f079b73a9
--- /dev/null
+++ b/src/lib/libc/stdlib/strtod.3
@@ -0,0 +1,167 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strtod.3,v 1.19 2014/01/19 10:39:00 schwarze Exp $
33.\"
34.Dd $Mdocdate: January 19 2014 $
35.Dt STRTOD 3
36.Os
37.Sh NAME
38.Nm strtod ,
39.Nm strtof ,
40.Nm strtold
41.Nd convert ASCII string to double, float or long double
42.Sh SYNOPSIS
43.In stdlib.h
44.Ft double
45.Fn strtod "const char *nptr" "char **endptr"
46.Pp
47.Ft float
48.Fn strtof "const char *nptr" "char **endptr"
49.Pp
50.Ft long double
51.Fn strtold "const char *nptr" "char **endptr"
52.Sh DESCRIPTION
53The
54.Fn strtod
55function converts the initial portion of the string pointed to by
56.Fa nptr
57to
58.Li double
59representation.
60The
61.Fn strtof
62function converts the initial portion of the string pointed to by
63.Fa nptr
64to
65.Li float
66representation.
67The
68.Fn strtold
69function converts the initial portion of the string pointed to by
70.Fa nptr
71to
72.Li long double
73representation.
74.Pp
75The expected form of the string is an optional plus
76.Pq Ql +
77or minus sign
78.Pq Ql -
79followed by a sequence of digits optionally containing
80a decimal-point character, optionally followed by an exponent.
81An exponent consists of an
82.Sq E
83or
84.Sq e ,
85followed by an optional plus or minus sign, followed by a sequence of digits.
86.Pp
87Alternatively, if the portion of the string following the optional
88plus or minus sign begins with
89.Dq INF
90or
91.Dq NAN ,
92ignoring case, it is interpreted as an infinity or a quiet \*(Na,
93respectively.
94The syntax
95.Dq NAN Ns Pq Ar s ,
96where
97.Ar s
98is an alphanumeric string, produces the same value as the call
99.Fo nan
100.Qq Ar s Ns
101.Fc
102(respectively,
103.Fo nanf
104.Qq Ar s Ns
105.Fc
106and
107.Fo nanl
108.Qq Ar s Ns
109.Fc . )
110.Pp
111In any of the above cases, leading whitespace characters in the
112string (as defined by the
113.Xr isspace 3
114function) are skipped.
115.Sh RETURN VALUES
116The
117.Fn strtod ,
118.Fn strtof
119and
120.Fn strtold
121functions return the converted value, if any.
122.Pp
123If
124.Fa endptr
125is not
126.Dv NULL ,
127a pointer to the character after the last character used
128in the conversion is stored in the location referenced by
129.Fa endptr .
130.Pp
131If no conversion is performed, zero is returned and the value of
132.Fa nptr
133is stored in the location referenced by
134.Fa endptr .
135.Pp
136If the correct value would cause overflow, plus or minus
137.Dv HUGE_VAL
138is returned (according to the sign of the value), and
139.Er ERANGE
140is stored in
141.Va errno .
142If the correct value would cause underflow, zero is returned and
143.Er ERANGE
144is stored in
145.Va errno .
146.Sh ERRORS
147.Bl -tag -width Er
148.It Bq Er ERANGE
149Overflow or underflow occurred.
150.El
151.Sh SEE ALSO
152.Xr atof 3 ,
153.Xr atoi 3 ,
154.Xr atol 3 ,
155.Xr strtol 3 ,
156.Xr strtoul 3
157.Sh STANDARDS
158The
159.Fn strtod
160function conforms to
161.St -ansiC-89 .
162The
163.Fn strtof
164and
165.Fn strtold
166functions conform to
167.St -ansiC-99 .
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
new file mode 100644
index 0000000000..c0a60979d9
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.3
@@ -0,0 +1,264 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strtol.3,v 1.24 2013/08/14 06:32:28 jmc Exp $
33.\"
34.Dd $Mdocdate: August 14 2013 $
35.Dt STRTOL 3
36.Os
37.Sh NAME
38.Nm strtol ,
39.Nm strtoll ,
40.Nm strtoimax ,
41.Nm strtoq ,
42.Nd convert string value to a long, long long or intmax_t integer
43.Sh SYNOPSIS
44.In limits.h
45.In stdlib.h
46.Ft long
47.Fn strtol "const char *nptr" "char **endptr" "int base"
48.Pp
49.Ft long long
50.Fn strtoll "const char *nptr" "char **endptr" "int base"
51.Pp
52.In inttypes.h
53.Ft intmax_t
54.Fn strtoimax "const char *nptr" "char **endptr" "int base"
55.Pp
56.In sys/types.h
57.In limits.h
58.In stdlib.h
59.Ft quad_t
60.Fn strtoq "const char *nptr" "char **endptr" "int base"
61.Sh DESCRIPTION
62The
63.Fn strtol
64function converts the string in
65.Fa nptr
66to a
67.Li long
68value.
69The
70.Fn strtoll
71function converts the string in
72.Fa nptr
73to a
74.Li long long
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.
88The conversion is done according to the given
89.Fa base ,
90which must be a number between 2 and 36 inclusive or the special value 0.
91.Pp
92The string may begin with an arbitrary amount of whitespace
93(as determined by
94.Xr isspace 3 )
95followed by a single optional
96.Ql +
97or
98.Ql -
99sign.
100If
101.Fa base
102is zero or 16, the string may then include a
103.Ql 0x
104prefix, and the number will be read in base 16; otherwise, a zero
105.Fa base
106is taken as 10 (decimal) unless the next character is
107.Ql 0 ,
108in which case it is taken as 8 (octal).
109.Pp
110The remainder of the string is converted to a
111.Li long ,
112.Li long long ,
113or
114.Li intmax_t ,
115value in the obvious manner,
116stopping at the first character which is not a valid digit
117in the given base.
118(In bases above 10, the letter
119.Ql A
120in either upper or lower case represents 10,
121.Ql B
122represents 11, and so forth, with
123.Ql Z
124representing 35.)
125.Pp
126If
127.Fa endptr
128is non-null,
129.Fn strtol
130stores the address of the first invalid character in
131.Fa *endptr .
132If there were no digits at all, however,
133.Fn strtol
134stores the original value of
135.Fa nptr
136in
137.Fa *endptr .
138(Thus, if
139.Fa *nptr
140is not
141.Ql \e0
142but
143.Fa **endptr
144is
145.Ql \e0
146on return, the entire string was valid.)
147.Sh RETURN VALUES
148The
149.Fn strtol ,
150.Fn strtoll ,
151.Fn strtoimax ,
152and
153.Fn strtoq
154functions return the result of the conversion,
155unless the value would underflow or overflow.
156If no conversion could be performed, 0 is returned;
157the global variable
158.Va errno
159is also set to
160.Er EINVAL ,
161though this is not portable across all platforms.
162If overflow or underflow occurs,
163.Va errno
164is set to
165.Er ERANGE
166and the function return value is as follows:
167.Bl -column "strtoimaxXX" "INTMAX_MIN" "INTMAX_MAX" -offset indent
168.It Sy Function Ta Sy underflow Ta Sy overflow
169.It Fn strtol Ta Dv LONG_MIN Ta Dv LONG_MAX
170.It Fn strtoll Ta Dv LLONG_MIN Ta Dv LLONG_MAX
171.It Fn strtoimax Ta Dv INTMAX_MIN Ta Dv INTMAX_MAX
172.It Fn strtoq Ta Dv LLONG_MIN Ta Dv LLONG_MAX
173.El
174.Sh EXAMPLES
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
236.Sh ERRORS
237.Bl -tag -width Er
238.It Bq Er ERANGE
239The given string was out of range; the value converted has been clamped.
240.El
241.Sh SEE ALSO
242.Xr atof 3 ,
243.Xr atoi 3 ,
244.Xr atol 3 ,
245.Xr atoll 3 ,
246.Xr sscanf 3 ,
247.Xr strtod 3 ,
248.Xr strtonum 3 ,
249.Xr strtoul 3
250.Sh STANDARDS
251The
252.Fn strtol ,
253.Fn strtoll ,
254and
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.
263.Sh BUGS
264Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000000..dc2cf8871c
--- /dev/null
+++ b/src/lib/libc/stdlib/strtol.c
@@ -0,0 +1,151 @@
1/* $OpenBSD: strtol.c,v 1.9 2013/04/17 17:40:35 tedu Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <ctype.h>
32#include <errno.h>
33#include <limits.h>
34#include <stdlib.h>
35
36
37/*
38 * Convert a string to a long integer.
39 *
40 * Ignores `locale' stuff. Assumes that the upper and lower case
41 * alphabets and digits are each contiguous.
42 */
43long
44strtol(const char *nptr, char **endptr, int base)
45{
46 const char *s;
47 long acc, cutoff;
48 int c;
49 int neg, any, cutlim;
50
51 /*
52 * Ensure that base is between 2 and 36 inclusive, or the special
53 * value of 0.
54 */
55 if (base != 0 && (base < 2 || base > 36)) {
56 if (endptr != 0)
57 *endptr = (char *)nptr;
58 errno = EINVAL;
59 return 0;
60 }
61
62 /*
63 * Skip white space and pick up leading +/- sign if any.
64 * If base is 0, allow 0x for hex and 0 for octal, else
65 * assume decimal; if base is already 16, allow 0x.
66 */
67 s = nptr;
68 do {
69 c = (unsigned char) *s++;
70 } while (isspace(c));
71 if (c == '-') {
72 neg = 1;
73 c = *s++;
74 } else {
75 neg = 0;
76 if (c == '+')
77 c = *s++;
78 }
79 if ((base == 0 || base == 16) &&
80 c == '0' && (*s == 'x' || *s == 'X')) {
81 c = s[1];
82 s += 2;
83 base = 16;
84 }
85 if (base == 0)
86 base = c == '0' ? 8 : 10;
87
88 /*
89 * Compute the cutoff value between legal numbers and illegal
90 * numbers. That is the largest legal value, divided by the
91 * base. An input number that is greater than this value, if
92 * followed by a legal input character, is too big. One that
93 * is equal to this value may be valid or not; the limit
94 * between valid and invalid numbers is then based on the last
95 * digit. For instance, if the range for longs is
96 * [-2147483648..2147483647] and the input base is 10,
97 * cutoff will be set to 214748364 and cutlim to either
98 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
99 * a value > 214748364, or equal but the next digit is > 7 (or 8),
100 * the number is too big, and we will return a range error.
101 *
102 * Set any if any `digits' consumed; make it negative to indicate
103 * overflow.
104 */
105 cutoff = neg ? LONG_MIN : LONG_MAX;
106 cutlim = cutoff % base;
107 cutoff /= base;
108 if (neg) {
109 if (cutlim > 0) {
110 cutlim -= base;
111 cutoff += 1;
112 }
113 cutlim = -cutlim;
114 }
115 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
116 if (isdigit(c))
117 c -= '0';
118 else if (isalpha(c))
119 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
120 else
121 break;
122 if (c >= base)
123 break;
124 if (any < 0)
125 continue;
126 if (neg) {
127 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
128 any = -1;
129 acc = LONG_MIN;
130 errno = ERANGE;
131 } else {
132 any = 1;
133 acc *= base;
134 acc -= c;
135 }
136 } else {
137 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
138 any = -1;
139 acc = LONG_MAX;
140 errno = ERANGE;
141 } else {
142 any = 1;
143 acc *= base;
144 acc += c;
145 }
146 }
147 }
148 if (endptr != 0)
149 *endptr = (char *) (any ? s - 1 : nptr);
150 return (acc);
151}
diff --git a/src/lib/libc/stdlib/strtoll.c b/src/lib/libc/stdlib/strtoll.c
new file mode 100644
index 0000000000..4bcc5565be
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoll.c
@@ -0,0 +1,144 @@
1/* $OpenBSD: strtoll.c,v 1.7 2013/03/28 18:09:38 martynas Exp $ */
2/*-
3 * Copyright (c) 1992 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/types.h>
32
33#include <ctype.h>
34#include <errno.h>
35#include <limits.h>
36#include <stdlib.h>
37
38/*
39 * Convert a string to a long long.
40 *
41 * Ignores `locale' stuff. Assumes that the upper and lower case
42 * alphabets and digits are each contiguous.
43 */
44long long
45strtoll(const char *nptr, char **endptr, int base)
46{
47 const char *s;
48 long long acc, cutoff;
49 int c;
50 int neg, any, cutlim;
51
52 /*
53 * Skip white space and pick up leading +/- sign if any.
54 * If base is 0, allow 0x for hex and 0 for octal, else
55 * assume decimal; if base is already 16, allow 0x.
56 */
57 s = nptr;
58 do {
59 c = (unsigned char) *s++;
60 } while (isspace(c));
61 if (c == '-') {
62 neg = 1;
63 c = *s++;
64 } else {
65 neg = 0;
66 if (c == '+')
67 c = *s++;
68 }
69 if ((base == 0 || base == 16) &&
70 c == '0' && (*s == 'x' || *s == 'X')) {
71 c = s[1];
72 s += 2;
73 base = 16;
74 }
75 if (base == 0)
76 base = c == '0' ? 8 : 10;
77
78 /*
79 * Compute the cutoff value between legal numbers and illegal
80 * numbers. That is the largest legal value, divided by the
81 * base. An input number that is greater than this value, if
82 * followed by a legal input character, is too big. One that
83 * is equal to this value may be valid or not; the limit
84 * between valid and invalid numbers is then based on the last
85 * digit. For instance, if the range for long longs is
86 * [-9223372036854775808..9223372036854775807] and the input base
87 * is 10, cutoff will be set to 922337203685477580 and cutlim to
88 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
89 * accumulated a value > 922337203685477580, or equal but the
90 * next digit is > 7 (or 8), the number is too big, and we will
91 * return a range error.
92 *
93 * Set any if any `digits' consumed; make it negative to indicate
94 * overflow.
95 */
96 cutoff = neg ? LLONG_MIN : LLONG_MAX;
97 cutlim = cutoff % base;
98 cutoff /= base;
99 if (neg) {
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++) {
107 if (isdigit(c))
108 c -= '0';
109 else if (isalpha(c))
110 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
111 else
112 break;
113 if (c >= base)
114 break;
115 if (any < 0)
116 continue;
117 if (neg) {
118 if (acc < cutoff || (acc == cutoff && c > cutlim)) {
119 any = -1;
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 }
137 }
138 }
139 if (endptr != 0)
140 *endptr = (char *) (any ? s - 1 : nptr);
141 return (acc);
142}
143
144__strong_alias(strtoq, strtoll);
diff --git a/src/lib/libc/stdlib/strtonum.3 b/src/lib/libc/stdlib/strtonum.3
new file mode 100644
index 0000000000..ed638cdbe2
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.3
@@ -0,0 +1,152 @@
1.\" $OpenBSD: strtonum.3,v 1.17 2013/08/14 06:32:28 jmc Exp $
2.\"
3.\" Copyright (c) 2004 Ted Unangst
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: August 14 2013 $
18.Dt STRTONUM 3
19.Os
20.Sh NAME
21.Nm strtonum
22.Nd reliably convert string value to an integer
23.Sh SYNOPSIS
24.In stdlib.h
25.Ft long long
26.Fo strtonum
27.Fa "const char *nptr"
28.Fa "long long minval"
29.Fa "long long maxval"
30.Fa "const char **errstr"
31.Fc
32.Sh DESCRIPTION
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 Qq too large
123The result was larger than the provided maximum value.
124.It Qq too small
125The result was smaller than the provided minimum value.
126.It Qq 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..1aeee3467b
--- /dev/null
+++ b/src/lib/libc/stdlib/strtonum.c
@@ -0,0 +1,65 @@
1/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */
2
3/*
4 * Copyright (c) 2004 Ted Unangst and Todd Miller
5 * All rights reserved.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <errno.h>
21#include <limits.h>
22#include <stdlib.h>
23
24#define INVALID 1
25#define TOOSMALL 2
26#define TOOLARGE 3
27
28long long
29strtonum(const char *numstr, long long minval, long long maxval,
30 const char **errstrp)
31{
32 long long ll = 0;
33 int error = 0;
34 char *ep;
35 struct errval {
36 const char *errstr;
37 int err;
38 } ev[4] = {
39 { NULL, 0 },
40 { "invalid", EINVAL },
41 { "too small", ERANGE },
42 { "too large", ERANGE },
43 };
44
45 ev[0].err = errno;
46 errno = 0;
47 if (minval > maxval) {
48 error = INVALID;
49 } else {
50 ll = strtoll(numstr, &ep, 10);
51 if (numstr == ep || *ep != '\0')
52 error = INVALID;
53 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54 error = TOOSMALL;
55 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56 error = TOOLARGE;
57 }
58 if (errstrp != NULL)
59 *errstrp = ev[error].errstr;
60 errno = ev[error].err;
61 if (error)
62 ll = 0;
63
64 return (ll);
65}
diff --git a/src/lib/libc/stdlib/strtoul.3 b/src/lib/libc/stdlib/strtoul.3
new file mode 100644
index 0000000000..1353637d68
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,245 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strtoul.3,v 1.22 2013/08/14 06:32:28 jmc Exp $
33.\"
34.Dd $Mdocdate: August 14 2013 $
35.Dt STRTOUL 3
36.Os
37.Sh NAME
38.Nm strtoul ,
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
43.Sh SYNOPSIS
44.In limits.h
45.In stdlib.h
46.Ft unsigned long
47.Fn strtoul "const char *nptr" "char **endptr" "int base"
48.Ft unsigned long long
49.Fn strtoull "const char *nptr" "char **endptr" "int base"
50.In inttypes.h
51.Ft uintmax_t
52.Fn strtoumax "const char *nptr" "char **endptr" "int base"
53.In sys/types.h
54.In limits.h
55.In stdlib.h
56.Ft u_quad_t
57.Fn strtouq "const char *nptr" "char **endptr" "int base"
58.Sh DESCRIPTION
59The
60.Fn strtoul
61function converts the string in
62.Fa nptr
63to an
64.Li unsigned long
65value.
66The
67.Fn strtoull
68function converts the string in
69.Fa nptr
70to an
71.Li unsigned long long
72value.
73The
74.Fn strtoumax
75function converts the string in
76.Fa nptr
77to a
78.Li umaxint_t
79value.
80The
81.Fn strtouq
82function is a deprecated equivalent of
83.Fn strtoull
84and is provided for backwards compatibility with legacy programs.
85The conversion is done according to the given
86.Fa base ,
87which must be a number between 2 and 36 inclusive
88or the special value 0.
89If the string in
90.Fa nptr
91represents a negative number, it will be converted to its unsigned equivalent.
92This behavior is consistent with what happens when a signed integer type is
93cast to its unsigned counterpart.
94.Pp
95The string may begin with an arbitrary amount of whitespace
96(as determined by
97.Xr isspace 3 )
98followed by a single optional
99.Ql +
100or
101.Ql -
102sign.
103If
104.Fa base
105is zero or 16, the string may then include a
106.Ql 0x
107prefix, and the number will be read in base 16; otherwise, a zero
108.Fa base
109is taken as 10 (decimal) unless the next character is
110.Ql 0 ,
111in which case it is taken as 8 (octal).
112.Pp
113The remainder of the string is converted to an
114.Li unsigned long
115value in the obvious manner, stopping at the end of the string
116or at the first character that does not produce a valid digit
117in the given base.
118(In bases above 10, the letter
119.Ql A
120in either upper or lower case represents 10,
121.Ql B
122represents 11, and so forth, with
123.Ql Z
124representing 35.)
125.Pp
126If
127.Fa endptr
128is non-null,
129.Fn strtoul
130stores the address of the first invalid character in
131.Fa *endptr .
132If there were no digits at all, however,
133.Fn strtoul
134stores the original value of
135.Fa nptr
136in
137.Fa *endptr .
138(Thus, if
139.Fa *nptr
140is not
141.Ql \e0
142but
143.Fa **endptr
144is
145.Ql \e0
146on return, the entire string was valid.)
147.Sh RETURN VALUES
148The
149.Fn strtoul ,
150.Fn strtoull ,
151.Fn strtoumax
152and
153.Fn strtouq
154functions return either the result of the conversion or,
155if there was a leading minus sign,
156the negation of the result of the conversion,
157unless the original (non-negated) value would overflow.
158If overflow occurs,
159.Fn strtoul
160returns
161.Dv ULONG_MAX ,
162.Fn strtoull
163returns
164.Dv ULLONG_MAX ,
165.Fn strtoumax
166returns
167.Dv UINTMAX_MAX ,
168.Fn strtouq
169returns
170.Dv ULLONG_MAX
171and the global variable
172.Va errno
173is set to
174.Er ERANGE .
175If no conversion could be performed, 0 is returned;
176the global variable
177.Va errno
178is also set to
179.Er EINVAL ,
180though this is not portable across all platforms.
181.Pp
182There is no way to determine if
183.Fn strtoul
184has processed a negative number (and returned an unsigned value) short of
185examining the string in
186.Fa nptr
187directly.
188.Sh EXAMPLES
189Ensuring that a string is a valid number (i.e., in range and containing no
190trailing characters) requires clearing
191.Va errno
192beforehand explicitly since
193.Va errno
194is not changed on a successful call to
195.Fn strtoul ,
196and the return value of
197.Fn strtoul
198cannot be used unambiguously to signal an error:
199.Bd -literal -offset indent
200char *ep;
201unsigned long ulval;
202
203\&...
204
205errno = 0;
206ulval = strtoul(buf, &ep, 10);
207if (buf[0] == '\e0' || *ep != '\e0')
208 goto not_a_number;
209if (errno == ERANGE && ulval == ULONG_MAX)
210 goto out_of_range;
211.Ed
212.Pp
213This example will accept
214.Dq 12
215but not
216.Dq 12foo
217or
218.Dq 12\en .
219If trailing whitespace is acceptable, further checks must be done on
220.Va *ep ;
221alternately, use
222.Xr sscanf 3 .
223.Sh ERRORS
224.Bl -tag -width Er
225.It Bq Er ERANGE
226The given string was out of range; the value converted has been clamped.
227.El
228.Sh SEE ALSO
229.Xr sscanf 3 ,
230.Xr strtol 3
231.Sh STANDARDS
232The
233.Fn strtoul ,
234.Fn strtoull ,
235and
236.Fn strtoumax
237functions conform to
238.St -ansiC-99 .
239The
240.Fn strtouq
241function is a
242.Bx
243extension and is provided for backwards compatibility with legacy programs.
244.Sh BUGS
245Ignores the current locale.
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
new file mode 100644
index 0000000000..a236365d2f
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: strtoul.c,v 1.8 2013/04/17 17:40:35 tedu Exp $ */
2/*
3 * Copyright (c) 1990 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <ctype.h>
32#include <errno.h>
33#include <limits.h>
34#include <stdlib.h>
35
36/*
37 * Convert a string to an unsigned long integer.
38 *
39 * Ignores `locale' stuff. Assumes that the upper and lower case
40 * alphabets and digits are each contiguous.
41 */
42unsigned long
43strtoul(const char *nptr, char **endptr, int base)
44{
45 const char *s;
46 unsigned long acc, cutoff;
47 int c;
48 int neg, any, cutlim;
49
50 /*
51 * See strtol 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 = ULONG_MAX / (unsigned long)base;
75 cutlim = ULONG_MAX % (unsigned long)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 = ULONG_MAX;
90 errno = ERANGE;
91 } else {
92 any = 1;
93 acc *= (unsigned long)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/strtoull.c b/src/lib/libc/stdlib/strtoull.c
new file mode 100644
index 0000000000..28f613a087
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoull.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: strtoull.c,v 1.6 2013/03/28 18:09:38 martynas Exp $ */
2/*-
3 * Copyright (c) 1992 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/types.h>
32
33#include <ctype.h>
34#include <errno.h>
35#include <limits.h>
36#include <stdlib.h>
37
38/*
39 * Convert a string to an unsigned long long.
40 *
41 * Ignores `locale' stuff. Assumes that the upper and lower case
42 * alphabets and digits are each contiguous.
43 */
44unsigned long long
45strtoull(const char *nptr, char **endptr, int base)
46{
47 const char *s;
48 unsigned long long acc, cutoff;
49 int c;
50 int neg, any, cutlim;
51
52 /*
53 * See strtoq for comments as to the logic used.
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 cutoff = ULLONG_MAX / (unsigned long long)base;
77 cutlim = ULLONG_MAX % (unsigned long long)base;
78 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
79 if (isdigit(c))
80 c -= '0';
81 else if (isalpha(c))
82 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
83 else
84 break;
85 if (c >= base)
86 break;
87 if (any < 0)
88 continue;
89 if (acc > cutoff || (acc == cutoff && c > cutlim)) {
90 any = -1;
91 acc = ULLONG_MAX;
92 errno = ERANGE;
93 } else {
94 any = 1;
95 acc *= (unsigned long long)base;
96 acc += c;
97 }
98 }
99 if (neg && any > 0)
100 acc = -acc;
101 if (endptr != 0)
102 *endptr = (char *) (any ? s - 1 : nptr);
103 return (acc);
104}
105
106__strong_alias(strtouq, strtoull);
diff --git a/src/lib/libc/stdlib/strtoumax.c b/src/lib/libc/stdlib/strtoumax.c
new file mode 100644
index 0000000000..ce6e2c00f1
--- /dev/null
+++ b/src/lib/libc/stdlib/strtoumax.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: strtoumax.c,v 1.1 2006/01/13 17:58:09 millert Exp $ */
2
3/*-
4 * Copyright (c) 1992 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <ctype.h>
33#include <errno.h>
34#include <inttypes.h>
35
36/*
37 * Convert a string to a uintmax_t.
38 *
39 * Ignores `locale' stuff. Assumes that the upper and lower case
40 * alphabets and digits are each contiguous.
41 */
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
new file mode 100644
index 0000000000..878bb0a9d2
--- /dev/null
+++ b/src/lib/libc/stdlib/system.3
@@ -0,0 +1,109 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" 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. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: system.3,v 1.13 2013/07/18 10:14:50 schwarze Exp $
33.\"
34.Dd $Mdocdate: July 18 2013 $
35.Dt SYSTEM 3
36.Os
37.Sh NAME
38.Nm system
39.Nd pass a command to the shell
40.Sh SYNOPSIS
41.In stdlib.h
42.Ft int
43.Fn system "const char *string"
44.Sh DESCRIPTION
45The
46.Fn system
47function hands the argument
48.Fa string
49to the command interpreter
50.Xr sh 1 .
51The calling process waits for the shell to finish executing the command,
52ignoring
53.Dv SIGINT
54and
55.Dv SIGQUIT ,
56and blocking
57.Dv SIGCHLD .
58.Pp
59If
60.Fa string
61is
62.Dv NULL ,
63.Fn system
64will return non-zero.
65Otherwise,
66.Fn system
67returns the termination status of the shell in the format specified by
68.Xr waitpid 2 .
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
75If a child process cannot be created, or the termination status of
76the shell cannot be obtained,
77.Fn system
78returns \-1 and sets
79.Va errno
80to indicate the error.
81If execution of the shell fails,
82.Fn system
83returns the termination status for a program that terminates with a call of
84.Fn exit 127 .
85.Sh SEE ALSO
86.Xr sh 1 ,
87.Xr execve 2 ,
88.Xr waitpid 2 ,
89.Xr popen 3
90.Sh STANDARDS
91The
92.Fn system
93function conforms to
94.St -ansiC
95and
96.St -p1003.2-92 .
97.Sh HISTORY
98The
99.Fn system
100function first appeared in
101.At v6 .
102.Sh CAVEATS
103Never supply the
104.Fn system
105function with a command containing any part of an unsanitized user-supplied
106string.
107Shell meta-characters present will be honored by the
108.Xr sh 1
109command interpreter.
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
new file mode 100644
index 0000000000..14ddcae8d3
--- /dev/null
+++ b/src/lib/libc/stdlib/system.c
@@ -0,0 +1,74 @@
1/* $OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1988 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/types.h>
32#include <sys/wait.h>
33#include <signal.h>
34#include <stdlib.h>
35#include <unistd.h>
36#include <paths.h>
37
38extern char **environ;
39
40int
41system(const char *command)
42{
43 pid_t pid;
44 sig_t intsave, quitsave;
45 sigset_t mask, omask;
46 int pstat;
47 char *argp[] = {"sh", "-c", NULL, NULL};
48
49 if (!command) /* just checking... */
50 return(1);
51
52 argp[2] = (char *)command;
53
54 sigemptyset(&mask);
55 sigaddset(&mask, SIGCHLD);
56 sigprocmask(SIG_BLOCK, &mask, &omask);
57 switch (pid = vfork()) {
58 case -1: /* error */
59 sigprocmask(SIG_SETMASK, &omask, NULL);
60 return(-1);
61 case 0: /* child */
62 sigprocmask(SIG_SETMASK, &omask, NULL);
63 execve(_PATH_BSHELL, argp, environ);
64 _exit(127);
65 }
66
67 intsave = signal(SIGINT, SIG_IGN);
68 quitsave = signal(SIGQUIT, SIG_IGN);
69 pid = waitpid(pid, (int *)&pstat, 0);
70 sigprocmask(SIG_SETMASK, &omask, NULL);
71 (void)signal(SIGINT, intsave);
72 (void)signal(SIGQUIT, quitsave);
73 return (pid == -1 ? -1 : pstat);
74}
diff --git a/src/lib/libc/stdlib/tfind.c b/src/lib/libc/stdlib/tfind.c
new file mode 100644
index 0000000000..0d1d5196d8
--- /dev/null
+++ b/src/lib/libc/stdlib/tfind.c
@@ -0,0 +1,41 @@
1/* $OpenBSD: tfind.c,v 1.6 2014/03/16 18:38:30 guenther Exp $ */
2
3/*
4 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
5 * the AT&T man page says.
6 *
7 * The node_t structure is for internal use only
8 *
9 * Written by reading the System V Interface Definition, not the code.
10 *
11 * Totally public domain.
12 */
13/*LINTLIBRARY*/
14#include <search.h>
15
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..46d0bba10c
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.3
@@ -0,0 +1,130 @@
1.\" $OpenBSD: tsearch.3,v 1.19 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: June 5 2013 $
18.Dt TSEARCH 3
19.Os
20.Sh NAME
21.Nm tsearch ,
22.Nm tfind ,
23.Nm tdelete ,
24.Nm twalk
25.Nd manipulate binary search trees
26.Sh SYNOPSIS
27.In search.h
28.Ft void *
29.Fn tdelete "const void *key" "void **rootp" "int (*compar)(const void *, const void *)"
30.Ft void *
31.Fn tfind "const void *key" "void * const *rootp" "int (*compar)(const void *, const void *)"
32.Ft void *
33.Fn tsearch "const void *key" "void **rootp" "int (*compar)(const void *, const void *)"
34.Ft void
35.Fn twalk "const void *root" "void (*action)(const void *, VISIT, int)"
36.Sh DESCRIPTION
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.
71If the node to be deleted is the root of the binary search tree,
72.Fa rootp
73will be adjusted and an unspecified non-null pointer will be returned.
74It takes the same arguments as
75.Fn tfind
76and
77.Fn tsearch .
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 tdelete
100returns a pointer to the parent of the deleted node or an unspecified
101non-null pointer if the root node is deleted.
102.Pp
103.Fn tfind ,
104.Fn tsearch ,
105and
106.Fn tdelete
107return
108.Dv NULL
109if
110.Fa rootp
111is
112.Dv NULL
113or the datum cannot be found.
114.Pp
115The
116.Fn twalk
117function returns no value.
118.Sh SEE ALSO
119.Xr bsearch 3 ,
120.Xr lsearch 3
121.Sh STANDARDS
122These functions conform to
123.St -p1003.1-2008 .
124.Sh CAVEATS
125The value returned when deleting the root node was unspecified before
126the
127.St -p1003.1-2008
128standard, so users of the
129.Fn tdelete
130function should be wary of relying on a specific behaviour.
diff --git a/src/lib/libc/stdlib/tsearch.c b/src/lib/libc/stdlib/tsearch.c
new file mode 100644
index 0000000000..a141085d2b
--- /dev/null
+++ b/src/lib/libc/stdlib/tsearch.c
@@ -0,0 +1,119 @@
1/* $OpenBSD: tsearch.c,v 1.8 2014/03/16 18:38:30 guenther Exp $ */
2
3/*
4 * Tree search generalized from Knuth (6.2.2) Algorithm T just like
5 * the AT&T man page says.
6 *
7 * The node_t structure is for internal use only
8 *
9 * Written by reading the System V Interface Definition, not the code.
10 *
11 * Totally public domain.
12 */
13/*LINTLIBRARY*/
14
15#include <search.h>
16#include <stdlib.h>
17
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 = (node *)1;
60 node *q;
61 node *r;
62 int cmp;
63
64 if (rootp == (struct node_t **)0 || *rootp == (struct node_t *)0)
65 return ((struct node_t *)0);
66 while ((cmp = (*compar)(key, (*rootp)->key)) != 0) {
67 p = *rootp;
68 rootp = (cmp < 0) ?
69 &(*rootp)->left : /* follow left branch */
70 &(*rootp)->right; /* follow right branch */
71 if (*rootp == (struct node_t *)0)
72 return ((void *)0); /* key not found */
73 }
74 r = (*rootp)->right; /* D1: */
75 if ((q = (*rootp)->left) == (struct node_t *)0) /* Left (struct node_t *)0? */
76 q = r;
77 else if (r != (struct node_t *)0) { /* Right link is null? */
78 if (r->left == (struct node_t *)0) { /* D2: Find successor */
79 r->left = q;
80 q = r;
81 } else { /* D3: Find (struct node_t *)0 link */
82 for (q = r->left; q->left != (struct node_t *)0; q = r->left)
83 r = q;
84 r->left = q->right;
85 q->left = (*rootp)->left;
86 q->right = (*rootp)->right;
87 }
88 }
89 free((struct node_t *) *rootp); /* D4: Free node */
90 *rootp = q; /* link parent to new node */
91 return(p);
92}
93
94/* Walk the nodes of a tree */
95static void
96trecurse(node *root, void (*action)(const void *, VISIT, int), int level)
97{
98 if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
99 (*action)(root, leaf, level);
100 else {
101 (*action)(root, preorder, level);
102 if (root->left != (struct node_t *)0)
103 trecurse(root->left, action, level + 1);
104 (*action)(root, postorder, level);
105 if (root->right != (struct node_t *)0)
106 trecurse(root->right, action, level + 1);
107 (*action)(root, endorder, level);
108 }
109}
110
111/* Walk the nodes of a tree */
112void
113twalk(const void *vroot, void (*action)(const void *, VISIT, int))
114{
115 node *root = (node *)vroot;
116
117 if (root != (node *)0 && action != (void (*)(const void *, VISIT, int))0)
118 trecurse(root, action, 0);
119}
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
new file mode 100644
index 0000000000..1f6d756182
--- /dev/null
+++ b/src/lib/libc/string/Makefile.inc
@@ -0,0 +1,175 @@
1# $OpenBSD: Makefile.inc,v 1.34 2014/03/23 23:16:48 tedu Exp $
2
3# string sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string
5
6SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \
7 strcasecmp.c strcasestr.c strcoll.c strdup.c \
8 strerror.c strerror_r.c strlcat.c strmode.c strndup.c strnlen.c \
9 strsignal.c strtok.c strxfrm.c \
10 wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
11 wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \
12 wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \
13 wmemmove.c wmemset.c wcsdup.c \
14 timingsafe_bcmp.c wcscasecmp.c
15
16# machine-dependent net sources
17# m-d Makefile.inc must include sources for:
18# bcmp() bcopy() bzero() ffs() index() memchr() memcmp() memset()
19# rindex() strcat() strcmp() strcpy() strcspn() strlen() strlcpy()
20# strncat() strncmp() strncpy() strpbrk() strsep()
21# strspn() strstr() swav()
22# m-d Makefile.inc may include sources for:
23# memcpy() memmove() strchr() strrchr()
24
25.include "${LIBCSRCDIR}/arch/${MACHINE_CPU}/string/Makefile.inc"
26
27# if no machine specific memmove(3), build one out of bcopy(3).
28.if empty(SRCS:Mmemmove.S)
29OBJS+= memmove.o
30memmove.o: bcopy.c
31 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
32 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
33 @mv ${.TARGET}.tmp ${.TARGET}
34
35memmove.go: bcopy.c
36 ${CC} -g -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
37 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
38 @mv ${.TARGET}.tmp ${.TARGET}
39
40memmove.po: bcopy.c
41 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
42 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
43 @mv ${.TARGET}.tmp ${.TARGET}
44
45memmove.so: bcopy.c
46 ${CC} ${PICFLAG} -DPIC -DMEMMOVE ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
47 -o ${.TARGET}
48
49memmove.do: bcopy.c
50 ${CC} -DMEMMOVE ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \
51 -o ${.TARGET}
52 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
53 @mv ${.TARGET}.tmp ${.TARGET}
54.endif
55
56# if no machine specific memcpy(3), build one out of bcopy(3).
57# if there is a machine specific memmove(3), we'll assume it aliases
58# memcpy(3).
59.if empty(SRCS:Mmemcpy.S)
60.if empty(SRCS:Mmemmove.S)
61OBJS+= memcpy.o
62memcpy.o: bcopy.c
63 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
64 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
65 @mv ${.TARGET}.tmp ${.TARGET}
66
67memcpy.go: bcopy.c
68 ${CC} -g -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
69 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
70 @mv ${.TARGET}.tmp ${.TARGET}
71
72memcpy.po: bcopy.c
73 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
74 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
75 @mv ${.TARGET}.tmp ${.TARGET}
76
77memcpy.so: bcopy.c
78 ${CC} ${PICFLAG} -DPIC -DMEMCOPY ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
79 -o ${.TARGET}
80
81memcpy.do: bcopy.c
82 ${CC} -DMEMCOPY ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \
83 -o ${.TARGET}
84 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
85 @mv ${.TARGET}.tmp ${.TARGET}
86.endif
87.endif
88
89# if no machine specific strchr(3), build one out of index(3).
90.if empty(SRCS:Mstrchr.S)
91OBJS+= strchr.o
92strchr.o: index.c
93 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
94 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
95 @mv ${.TARGET}.tmp ${.TARGET}
96
97strchr.go: index.c
98 ${CC} -g -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
99 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
100 @mv ${.TARGET}.tmp ${.TARGET}
101
102strchr.po: index.c
103 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
104 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
105 @mv ${.TARGET}.tmp ${.TARGET}
106
107strchr.so: index.c
108 ${CC} ${PICFLAG} -DPIC -DSTRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
109 -o ${.TARGET}
110
111strchr.do: index.c
112 ${CC} -DSTRCHR ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \
113 -o ${.TARGET}
114 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
115 @mv ${.TARGET}.tmp ${.TARGET}
116.endif
117
118# if no machine specific strrchr(3), build one out of rindex(3).
119.if empty(SRCS:Mstrrchr.S)
120OBJS+= strrchr.o
121strrchr.o: rindex.c
122 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
123 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
124 @mv ${.TARGET}.tmp ${.TARGET}
125
126strrchr.go: rindex.c
127 ${CC} -g -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} -o ${.TARGET}
128 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
129 @mv ${.TARGET}.tmp ${.TARGET}
130
131strrchr.po: rindex.c
132 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
133 @${LD} -o ${.TARGET}.tmp -X -r ${.TARGET}
134 @mv ${.TARGET}.tmp ${.TARGET}
135
136strrchr.so: rindex.c
137 ${CC} ${PICFLAG} -DPIC -DSTRRCHR ${CFLAGS} ${CPPFLAGS} -c ${.ALLSRC} \
138 -o ${.TARGET}
139
140strrchr.do: rindex.c
141 ${CC} -DSTRRCHR ${CFLAGS} ${CPPFLAGS} ${DIST_CFLAGS} -c ${.ALLSRC} \
142 -o ${.TARGET}
143 @${LD} -o ${.TARGET}.tmp -x -r ${.TARGET}
144 @mv ${.TARGET}.tmp ${.TARGET}
145.endif
146
147MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \
148 memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 stpcpy.3 strcasecmp.3 \
149 strcat.3 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 \
150 strerror.3 string.3 strlen.3 strmode.3 strncat.3 strncpy.3 strpbrk.3 \
151 strrchr.3 strsep.3 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 \
152 swab.3 strlcpy.3 wcscasecmp.3 wcscat.3 wcschr.3 wcscmp.3 wcscpy.3 \
153 wcscspn.3 wcsdup.3 wcslcpy.3 wcslen.3 wcspbrk.3 wcsrchr.3 wcsspn.3 \
154 wcsstr.3 wcstok.3 wcswidth.3 wmemchr.3 wmemcmp.3 wmemcpy.3 wmemmove.3 \
155 wmemset.3
156
157MLINKS+=bzero.3 explicit_bzero.3
158MLINKS+=memchr.3 memrchr.3
159MLINKS+=stpcpy.3 stpncpy.3
160MLINKS+=strchr.3 index.3
161MLINKS+=strrchr.3 rindex.3
162MLINKS+=strcasecmp.3 strncasecmp.3
163MLINKS+=strcmp.3 strncmp.3
164MLINKS+=strdup.3 strndup.3
165MLINKS+=strlcpy.3 strlcat.3
166MLINKS+=strlen.3 strnlen.3
167MLINKS+=strstr.3 strcasestr.3
168MLINKS+=strtok.3 strtok_r.3
169MLINKS+=strerror.3 strerror_r.3
170MLINKS+=wcscasecmp.3 wcsncasecmp.3
171MLINKS+=wcscat.3 wcsncat.3
172MLINKS+=wcscmp.3 wcsncmp.3
173MLINKS+=wcscpy.3 wcsncpy.3
174MLINKS+=wcslcpy.3 wcslcat.3
175MLINKS+=bcmp.3 timingsafe_bcmp.3
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
new file mode 100644
index 0000000000..52584b4b83
--- /dev/null
+++ b/src/lib/libc/string/bcmp.3
@@ -0,0 +1,88 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
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.\" $OpenBSD: bcmp.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt BCMP 3
34.Os
35.Sh NAME
36.Nm bcmp ,
37.Nm timingsafe_bcmp
38.Nd compare byte string
39.Sh SYNOPSIS
40.In string.h
41.Ft int
42.Fn bcmp "const void *b1" "const void *b2" "size_t len"
43.Ft int
44.Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len"
45.Sh DESCRIPTION
46The
47.Fn bcmp
48function compares byte string
49.Fa b1
50against byte string
51.Fa b2 ,
52returning zero if they are identical, non-zero otherwise.
53Both strings are assumed to be
54.Fa len
55bytes long.
56Zero-length strings are always identical.
57.Pp
58The strings may overlap.
59.Pp
60The
61.Fn timingsafe_bcmp
62function has the same semantics as
63.Fn bcmp ,
64but its running time is independent of the contents of
65.Fa b1
66and
67.Fa b2 ,
68making it safe to use for comparing secret values such as cryptographic MACs.
69In contrast,
70.Fn bcmp
71returns after finding the first differing byte,
72making it vulnerable to timing attacks.
73.Sh SEE ALSO
74.Xr memcmp 3 ,
75.Xr strcasecmp 3 ,
76.Xr strcmp 3 ,
77.Xr strcoll 3 ,
78.Xr strxfrm 3
79.Sh HISTORY
80The
81.Fn bcmp
82function first appeared in
83.Bx 4.2 .
84.Pp
85The
86.Fn timingsafe_bcmp
87function first appeared in
88.Ox 4.9 .
diff --git a/src/lib/libc/string/bcmp.c b/src/lib/libc/string/bcmp.c
new file mode 100644
index 0000000000..fd5c93121e
--- /dev/null
+++ b/src/lib/libc/string/bcmp.c
@@ -0,0 +1,55 @@
1/* $OpenBSD: bcmp.c,v 1.9 2008/03/19 03:00:23 ray Exp $ */
2
3/*
4 * Copyright (c) 1987 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#if !defined(_KERNEL) && !defined(_STANDALONE)
33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
37
38/*
39 * bcmp -- vax cmpc3 instruction
40 */
41int
42bcmp(const void *b1, const void *b2, size_t length)
43{
44 char *p1, *p2;
45
46 if (length == 0)
47 return (0);
48 p1 = (char *)b1;
49 p2 = (char *)b2;
50 do
51 if (*p1++ != *p2++)
52 return (1);
53 while (--length);
54 return (0);
55}
diff --git a/src/lib/libc/string/bcopy.3 b/src/lib/libc/string/bcopy.3
new file mode 100644
index 0000000000..94a8231fcb
--- /dev/null
+++ b/src/lib/libc/string/bcopy.3
@@ -0,0 +1,67 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\"
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.\" $OpenBSD: bcopy.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
32.\"
33.Dd $Mdocdate: June 5 2013 $
34.Dt BCOPY 3
35.Os
36.Sh NAME
37.Nm bcopy
38.Nd copy bytes
39.Sh SYNOPSIS
40.In string.h
41.Ft void
42.Fn bcopy "const void *src" "void *dst" "size_t len"
43.Sh DESCRIPTION
44The
45.Fn bcopy
46function copies
47.Fa len
48bytes from buffer
49.Fa src
50to buffer
51.Fa dst .
52The two buffers may overlap.
53If
54.Fa len
55is zero, no bytes are copied.
56.Sh SEE ALSO
57.Xr memccpy 3 ,
58.Xr memcpy 3 ,
59.Xr memmove 3 ,
60.Xr strcpy 3 ,
61.Xr strlcpy 3 ,
62.Xr strncpy 3
63.Sh HISTORY
64The
65.Fn bcopy
66function first appeared in
67.Bx 4.2 .
diff --git a/src/lib/libc/string/bcopy.c b/src/lib/libc/string/bcopy.c
new file mode 100644
index 0000000000..4308c6484a
--- /dev/null
+++ b/src/lib/libc/string/bcopy.c
@@ -0,0 +1,128 @@
1/* $OpenBSD: bcopy.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * sizeof(word) MUST BE A POWER OF TWO
38 * SO THAT wmask BELOW IS ALL ONES
39 */
40typedef long word; /* "word" used for optimal copy speed */
41
42#define wsize sizeof(word)
43#define wmask (wsize - 1)
44
45/*
46 * Copy a block of memory, handling overlap.
47 * This is the routine that actually implements
48 * (the portable versions of) bcopy, memcpy, and memmove.
49 */
50#ifdef MEMCOPY
51void *
52memcpy(void *dst0, const void *src0, size_t length)
53#else
54#ifdef MEMMOVE
55void *
56memmove(void *dst0, const void *src0, size_t length)
57#else
58void
59bcopy(const void *src0, void *dst0, size_t length)
60#endif
61#endif
62{
63 char *dst = dst0;
64 const char *src = src0;
65 size_t t;
66
67 if (length == 0 || dst == src) /* nothing to do */
68 goto done;
69
70 /*
71 * Macros: loop-t-times; and loop-t-times, t>0
72 */
73#define TLOOP(s) if (t) TLOOP1(s)
74#define TLOOP1(s) do { s; } while (--t)
75
76 if ((unsigned long)dst < (unsigned long)src) {
77 /*
78 * Copy forward.
79 */
80 t = (long)src; /* only need low bits */
81 if ((t | (long)dst) & wmask) {
82 /*
83 * Try to align operands. This cannot be done
84 * unless the low bits match.
85 */
86 if ((t ^ (long)dst) & wmask || length < wsize)
87 t = length;
88 else
89 t = wsize - (t & wmask);
90 length -= t;
91 TLOOP1(*dst++ = *src++);
92 }
93 /*
94 * Copy whole words, then mop up any trailing bytes.
95 */
96 t = length / wsize;
97 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
98 t = length & wmask;
99 TLOOP(*dst++ = *src++);
100 } else {
101 /*
102 * Copy backwards. Otherwise essentially the same.
103 * Alignment works as before, except that it takes
104 * (t&wmask) bytes to align, not wsize-(t&wmask).
105 */
106 src += length;
107 dst += length;
108 t = (long)src;
109 if ((t | (long)dst) & wmask) {
110 if ((t ^ (long)dst) & wmask || length <= wsize)
111 t = length;
112 else
113 t &= wmask;
114 length -= t;
115 TLOOP1(*--dst = *--src);
116 }
117 t = length / wsize;
118 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
119 t = length & wmask;
120 TLOOP(*--dst = *--src);
121 }
122done:
123#if defined(MEMCOPY) || defined(MEMMOVE)
124 return (dst0);
125#else
126 return;
127#endif
128}
diff --git a/src/lib/libc/string/bstring.3 b/src/lib/libc/string/bstring.3
new file mode 100644
index 0000000000..d88b78f504
--- /dev/null
+++ b/src/lib/libc/string/bstring.3
@@ -0,0 +1,108 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
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.\" $OpenBSD: bstring.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt BSTRING 3
34.Os
35.Sh NAME
36.Nm bstring
37.Nd byte string operations
38.Sh SYNOPSIS
39.In string.h
40.Ft int
41.Fn bcmp "const void *b1" "const void *b2" "size_t len"
42.Ft void
43.Fn bcopy "const void *src" "void *dst" "size_t len"
44.Ft void
45.Fn bzero "void *b" "size_t len"
46.Ft void *
47.Fn memchr "const void *b" "int c" "size_t len"
48.Ft int
49.Fn memcmp "const void *b1" "const void *b2" "size_t len"
50.Ft void *
51.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
52.Ft void *
53.Fn memcpy "void *dst" "const void *src" "size_t len"
54.Ft void *
55.Fn memmove "void *dst" "const void *src" "size_t len"
56.Ft void *
57.Fn memset "void *b" "int c" "size_t len"
58.Sh DESCRIPTION
59These functions operate on variable length strings of bytes.
60They do not check for terminating NUL bytes as the routines
61listed in
62.Xr string 3
63do.
64.Pp
65See the specific manual pages for more information.
66.Sh SEE ALSO
67.Xr bcmp 3 ,
68.Xr bcopy 3 ,
69.Xr bzero 3 ,
70.Xr memccpy 3 ,
71.Xr memchr 3 ,
72.Xr memcmp 3 ,
73.Xr memcpy 3 ,
74.Xr memmove 3 ,
75.Xr memset 3
76.Sh STANDARDS
77The functions
78.Fn memchr ,
79.Fn memcmp ,
80.Fn memcpy ,
81.Fn memmove ,
82and
83.Fn memset
84conform to
85.St -ansiC .
86.Sh HISTORY
87The
88.Fn bcmp ,
89.Fn bcopy ,
90and
91.Fn bzero
92functions first appeared in
93.Bx 4.2 .
94The
95.Fn memchr ,
96.Fn memcmp ,
97.Fn memccpy ,
98.Fn memcpy ,
99and
100.Fn memset
101functions first appeared in
102.At V
103and were reimplemented for
104.Bx 4.3 Tahoe .
105The
106.Fn memmove
107function first appeared in
108.Bx 4.3 Reno .
diff --git a/src/lib/libc/string/bzero.3 b/src/lib/libc/string/bzero.3
new file mode 100644
index 0000000000..3e21c4241f
--- /dev/null
+++ b/src/lib/libc/string/bzero.3
@@ -0,0 +1,74 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
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.\" $OpenBSD: bzero.3,v 1.11 2014/01/22 22:21:25 jmc Exp $
31.\"
32.Dd $Mdocdate: January 22 2014 $
33.Dt BZERO 3
34.Os
35.Sh NAME
36.Nm bzero ,
37.Nm explicit_bzero
38.Nd write zeroes to a byte string
39.Sh SYNOPSIS
40.In string.h
41.Ft void
42.Fn bzero "void *b" "size_t len"
43.Ft void
44.Fn explicit_bzero "void *b" "size_t len"
45.Sh DESCRIPTION
46The
47.Fn bzero
48function writes
49.Fa len
50zero bytes to the string
51.Fa b .
52If
53.Fa len
54is zero,
55.Fn bzero
56does nothing.
57.Pp
58The
59.Fn explicit_bzero
60variant behaves the same, but will not be removed by a compiler's dead store
61optimization pass, making it useful for clearing sensitive memory such as a
62password.
63.Sh SEE ALSO
64.Xr memset 3 ,
65.Xr swab 3
66.Sh HISTORY
67The
68.Fn bzero
69function first appeared in
70.Bx 4.2 .
71The
72.Fn explicit_bzero
73function first appeared in
74.Ox 5.5 .
diff --git a/src/lib/libc/string/bzero.c b/src/lib/libc/string/bzero.c
new file mode 100644
index 0000000000..4d267d4f40
--- /dev/null
+++ b/src/lib/libc/string/bzero.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: bzero.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1987 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#if !defined(_KERNEL) && !defined(_STANDALONE)
33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
37
38/*
39 * bzero -- vax movc5 instruction
40 */
41void
42bzero(void *b, size_t length)
43{
44 char *p;
45
46 for (p = b; length--;)
47 *p++ = '\0';
48}
diff --git a/src/lib/libc/string/explicit_bzero.c b/src/lib/libc/string/explicit_bzero.c
new file mode 100644
index 0000000000..fd2948ca44
--- /dev/null
+++ b/src/lib/libc/string/explicit_bzero.c
@@ -0,0 +1,20 @@
1/* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */
2/*
3 * Public domain.
4 * Written by Ted Unangst
5 */
6
7#if !defined(_KERNEL) && !defined(_STANDALONE)
8#include <string.h>
9#else
10#include <lib/libkern/libkern.h>
11#endif
12
13/*
14 * explicit_bzero - don't let the compiler optimize away bzero
15 */
16void
17explicit_bzero(void *p, size_t n)
18{
19 bzero(p, n);
20}
diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3
new file mode 100644
index 0000000000..c0ed7baa9e
--- /dev/null
+++ b/src/lib/libc/string/ffs.3
@@ -0,0 +1,61 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. 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.\" $OpenBSD: ffs.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt FFS 3
34.Os
35.Sh NAME
36.Nm ffs
37.Nd find first bit set in a bit string
38.Sh SYNOPSIS
39.In string.h
40.Ft int
41.Fn ffs "int value"
42.Sh DESCRIPTION
43The
44.Fn ffs
45function finds the first bit set in
46.Fa value
47and returns the index of that bit.
48Bits are numbered starting from 1, starting at the rightmost bit.
49A return value of 0 means that the argument was zero.
50.Sh SEE ALSO
51.Xr bitstring 3
52.Sh STANDARDS
53The
54.Fn ffs
55function conforms to
56.St -p1003.1-2008 .
57.Sh HISTORY
58The
59.Fn ffs
60function first appeared in
61.Bx 4.2 .
diff --git a/src/lib/libc/string/ffs.c b/src/lib/libc/string/ffs.c
new file mode 100644
index 0000000000..7dec1613a8
--- /dev/null
+++ b/src/lib/libc/string/ffs.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: ffs.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Public domain.
5 * Written by Dale Rahn.
6 */
7
8#if !defined(_KERNEL) && !defined(_STANDALONE)
9#include <string.h>
10#else
11#include <lib/libkern/libkern.h>
12#endif
13
14/*
15 * ffs -- vax ffs instruction
16 */
17int
18ffs(int mask)
19{
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 }
42
43 return (bit + t[ r & 0xf ]);
44}
diff --git a/src/lib/libc/string/index.c b/src/lib/libc/string/index.c
new file mode 100644
index 0000000000..50e9ca35ab
--- /dev/null
+++ b/src/lib/libc/string/index.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: index.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <string.h>
32
33char *
34#ifdef STRCHR
35strchr(const char *p, int ch)
36#else
37index(const char *p, int ch)
38#endif
39{
40 for (;; ++p) {
41 if (*p == ch)
42 return((char *)p);
43 if (!*p)
44 return((char *)NULL);
45 }
46 /* NOTREACHED */
47}
diff --git a/src/lib/libc/string/memccpy.3 b/src/lib/libc/string/memccpy.3
new file mode 100644
index 0000000000..98326d6871
--- /dev/null
+++ b/src/lib/libc/string/memccpy.3
@@ -0,0 +1,81 @@
1.\" $OpenBSD: memccpy.3,v 1.12 2013/09/25 21:49:30 millert 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.\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd $Mdocdate: September 25 2013 $
33.Dt MEMCCPY 3
34.Os
35.Sh NAME
36.Nm memccpy
37.Nd copy string until character found
38.Sh SYNOPSIS
39.In string.h
40.Ft void *
41.Fn memccpy "void *dst" "const void *src" "int c" "size_t len"
42.Sh DESCRIPTION
43The
44.Fn memccpy
45function copies bytes from string
46.Fa src
47to string
48.Fa dst .
49If the character
50.Fa c
51(as converted to an
52.Li unsigned char )
53occurs in the string
54.Fa src ,
55the copy stops and a pointer to the byte after the copy of
56.Fa c
57in the string
58.Fa dst
59is returned.
60Otherwise,
61.Fa len
62bytes are copied, and a null pointer is returned.
63.Pp
64If the
65.Fa src
66and
67.Fa dst
68strings overlap, the behavior is undefined.
69.Sh SEE ALSO
70.Xr bcopy 3 ,
71.Xr memcpy 3 ,
72.Xr memmove 3 ,
73.Xr strcpy 3 ,
74.Xr strlcpy 3
75.Sh HISTORY
76The
77.Fn memccpy
78function first appeared in
79.At V
80and was reimplemented for
81.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/memccpy.c b/src/lib/libc/string/memccpy.c
new file mode 100644
index 0000000000..485c55fcab
--- /dev/null
+++ b/src/lib/libc/string/memccpy.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: memccpy.c,v 1.6 2005/08/08 08:05:37 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 <string.h>
33
34void *
35memccpy(void *t, const void *f, int c, size_t n)
36{
37
38 if (n) {
39 unsigned char *tp = t;
40 const unsigned char *fp = f;
41 unsigned char uc = c;
42 do {
43 if ((*tp++ = *fp++) == uc)
44 return (tp);
45 } while (--n != 0);
46 }
47 return (0);
48}
diff --git a/src/lib/libc/string/memchr.3 b/src/lib/libc/string/memchr.3
new file mode 100644
index 0000000000..8d8a9ddf9c
--- /dev/null
+++ b/src/lib/libc/string/memchr.3
@@ -0,0 +1,102 @@
1.\" $OpenBSD: memchr.3,v 1.12 2014/04/07 17:57:56 schwarze Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: April 7 2014 $
35.Dt MEMCHR 3
36.Os
37.Sh NAME
38.Nm memchr ,
39.Nm memrchr
40.Nd locate byte in byte string
41.Sh SYNOPSIS
42.In string.h
43.Ft void *
44.Fn memchr "const void *b" "int c" "size_t len"
45.Ft void *
46.Fn memrchr "const void *b" "int c" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn memchr
50function locates the first occurrence of
51.Fa c
52(converted to an
53.Li unsigned char )
54in string
55.Fa b .
56.Pp
57The
58.Fn memrchr
59function behaves like
60.Fn memchr ,
61except that it locates the last occurrence of
62.Fa c
63in string
64.Fa b .
65.Sh RETURN VALUES
66The
67.Fn memchr
68and
69.Fn memrchr
70functions return a pointer to the byte located, or
71.Dv NULL
72if no such byte exists within
73.Fa len
74bytes.
75.Sh SEE ALSO
76.Xr strchr 3 ,
77.Xr strcspn 3 ,
78.Xr strpbrk 3 ,
79.Xr strrchr 3 ,
80.Xr strsep 3 ,
81.Xr strspn 3 ,
82.Xr strstr 3 ,
83.Xr strtok 3 ,
84.Xr wmemchr 3
85.Sh STANDARDS
86The
87.Fn memchr
88function conforms to
89.St -ansiC .
90.Pp
91The
92.Fn memrchr
93function is an
94.Ox
95extension.
96.Sh HISTORY
97The
98.Fn memchr
99function first appeared in
100.At V
101and was reimplemented for
102.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/memchr.c b/src/lib/libc/string/memchr.c
new file mode 100644
index 0000000000..4573e3ceb1
--- /dev/null
+++ b/src/lib/libc/string/memchr.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: memchr.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36void *
37memchr(const void *s, int c, size_t n)
38{
39 if (n != 0) {
40 const unsigned char *p = s;
41
42 do {
43 if (*p++ == (unsigned char)c)
44 return ((void *)(p - 1));
45 } while (--n != 0);
46 }
47 return (NULL);
48}
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3
new file mode 100644
index 0000000000..ebd838825a
--- /dev/null
+++ b/src/lib/libc/string/memcmp.3
@@ -0,0 +1,85 @@
1.\" $OpenBSD: memcmp.3,v 1.8 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt MEMCMP 3
36.Os
37.Sh NAME
38.Nm memcmp
39.Nd compare byte string
40.Sh SYNOPSIS
41.In string.h
42.Ft int
43.Fn memcmp "const void *b1" "const void *b2" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn memcmp
47function compares byte string
48.Fa b1
49against byte string
50.Fa b2 .
51Both strings are assumed to be
52.Fa len
53bytes long.
54.Sh RETURN VALUES
55The
56.Fn memcmp
57function returns zero if the two strings are identical,
58otherwise returns the difference between the first two differing bytes
59(treated as
60.Li unsigned char
61values, so that
62.Sq Li \e200
63is greater than
64.Sq Li \&\e0 ,
65for example).
66Zero-length strings are always identical.
67.Sh SEE ALSO
68.Xr bcmp 3 ,
69.Xr strcasecmp 3 ,
70.Xr strcmp 3 ,
71.Xr strcoll 3 ,
72.Xr strxfrm 3 ,
73.Xr wmemcmp 3
74.Sh STANDARDS
75The
76.Fn memcmp
77function conforms to
78.St -ansiC .
79.Sh HISTORY
80The
81.Fn memcmp
82function first appeared in
83.At V
84and was reimplemented for
85.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/memcmp.c b/src/lib/libc/string/memcmp.c
new file mode 100644
index 0000000000..49384a6fb9
--- /dev/null
+++ b/src/lib/libc/string/memcmp.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: memcmp.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Compare memory regions.
38 */
39int
40memcmp(const void *s1, const void *s2, size_t n)
41{
42 if (n != 0) {
43 const unsigned char *p1 = s1, *p2 = s2;
44
45 do {
46 if (*p1++ != *p2++)
47 return (*--p1 - *--p2);
48 } while (--n != 0);
49 }
50 return (0);
51}
diff --git a/src/lib/libc/string/memcpy.3 b/src/lib/libc/string/memcpy.3
new file mode 100644
index 0000000000..8df2a785b9
--- /dev/null
+++ b/src/lib/libc/string/memcpy.3
@@ -0,0 +1,79 @@
1.\" $OpenBSD: memcpy.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt MEMCPY 3
36.Os
37.Sh NAME
38.Nm memcpy
39.Nd copy bytes
40.Sh SYNOPSIS
41.In string.h
42.Ft void *
43.Fn memcpy "void *dst" "const void *src" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn memcpy
47function copies
48.Fa len
49bytes from buffer
50.Fa src
51to buffer
52.Fa dst .
53If the two buffers may overlap,
54.Xr memmove 3
55must be used instead.
56.Sh RETURN VALUES
57The
58.Fn memcpy
59function returns the original value of
60.Fa dst .
61.Sh SEE ALSO
62.Xr bcopy 3 ,
63.Xr memccpy 3 ,
64.Xr memmove 3 ,
65.Xr strcpy 3 ,
66.Xr strlcpy 3 ,
67.Xr wmemcpy 3
68.Sh STANDARDS
69The
70.Fn memcpy
71function conforms to
72.St -ansiC .
73.Sh HISTORY
74The
75.Fn memcpy
76function first appeared in
77.At V
78and was reimplemented for
79.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/memmem.3 b/src/lib/libc/string/memmem.3
new file mode 100644
index 0000000000..b0b0bb966b
--- /dev/null
+++ b/src/lib/libc/string/memmem.3
@@ -0,0 +1,77 @@
1.\" $OpenBSD: memmem.3,v 1.2 2013/07/16 15:21:11 schwarze Exp $
2.\"
3.\" Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\" notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\" notice, this list of conditions and the following disclaimer in the
12.\" documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may not be used to endorse or promote
14.\" products derived from this software without specific prior written
15.\" permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27.\" SUCH DAMAGE.
28.\"
29.Dd $Mdocdate: July 16 2013 $
30.Dt MEMMEM 3
31.Os
32.Sh NAME
33.Nm memmem
34.Nd locate a byte substring in a byte string
35.Sh SYNOPSIS
36.In string.h
37.Ft "void *"
38.Fo memmem
39.Fa "const void *big" "size_t big_len"
40.Fa "const void *little" "size_t little_len"
41.Fc
42.Sh DESCRIPTION
43The
44.Fn memmem
45function
46locates the first occurrence of the byte string
47.Fa little
48in the byte string
49.Fa big .
50.Sh RETURN VALUES
51If
52.Fa little
53is zero length,
54.Fa big
55is returned; if
56.Fa little
57occurs nowhere in
58.Fa big ,
59.Dv NULL
60is returned;
61otherwise a pointer to the first character of the first occurrence of
62.Fa little
63is returned.
64.Sh SEE ALSO
65.Xr memchr 3 ,
66.Xr strchr 3 ,
67.Xr strstr 3
68.Sh STANDARDS
69.Fn memmem
70is a GNU extension.
71.Sh HISTORY
72The
73.Fn memmem
74function first appeared in
75.Ox 5.4 .
76.Sh AUTHORS
77.An Pascal Gloor Aq Mt pascal.gloor@spale.com
diff --git a/src/lib/libc/string/memmem.c b/src/lib/libc/string/memmem.c
new file mode 100644
index 0000000000..5793a7dfd7
--- /dev/null
+++ b/src/lib/libc/string/memmem.c
@@ -0,0 +1,63 @@
1/* $OpenBSD: memmem.c,v 1.3 2013/05/30 01:10:45 ajacoutot Exp $ */
2/*-
3 * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <string.h>
31
32/*
33 * Find the first occurrence of the byte string s in byte string l.
34 */
35
36void *
37memmem(const void *l, size_t l_len, const void *s, size_t s_len)
38{
39 const char *cur, *last;
40 const char *cl = l;
41 const char *cs = s;
42
43 /* a zero length needle should just return the haystack */
44 if (s_len == 0)
45 return (void *)cl;
46
47 /* "s" must be smaller or equal to "l" */
48 if (l_len < s_len)
49 return NULL;
50
51 /* special case where s_len == 1 */
52 if (s_len == 1)
53 return memchr(l, *cs, l_len);
54
55 /* the last position where its possible to find "s" in "l" */
56 last = cl + l_len - s_len;
57
58 for (cur = cl; cur <= last; cur++)
59 if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
60 return (void *)cur;
61
62 return NULL;
63}
diff --git a/src/lib/libc/string/memmove.3 b/src/lib/libc/string/memmove.3
new file mode 100644
index 0000000000..8665e4abcf
--- /dev/null
+++ b/src/lib/libc/string/memmove.3
@@ -0,0 +1,76 @@
1.\" $OpenBSD: memmove.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt MEMMOVE 3
36.Os
37.Sh NAME
38.Nm memmove
39.Nd copy bytes
40.Sh SYNOPSIS
41.In string.h
42.Ft void *
43.Fn memmove "void *dst" "const void *src" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn memmove
47function copies
48.Fa len
49bytes from buffer
50.Fa src
51to buffer
52.Fa dst .
53The two buffers may overlap;
54the copy is always done in a non-destructive manner.
55.Sh RETURN VALUES
56The
57.Fn memmove
58function returns the original value of
59.Fa dst .
60.Sh SEE ALSO
61.Xr bcopy 3 ,
62.Xr memccpy 3 ,
63.Xr memcpy 3 ,
64.Xr strcpy 3 ,
65.Xr strlcpy 3 ,
66.Xr wmemmove 3
67.Sh STANDARDS
68The
69.Fn memmove
70function conforms to
71.St -ansiC .
72.Sh HISTORY
73The
74.Fn memmove
75function first appeared in
76.Bx 4.3 Reno .
diff --git a/src/lib/libc/string/memrchr.c b/src/lib/libc/string/memrchr.c
new file mode 100644
index 0000000000..bd27ebc620
--- /dev/null
+++ b/src/lib/libc/string/memrchr.c
@@ -0,0 +1,38 @@
1/* $OpenBSD: memrchr.c,v 1.2 2007/11/27 16:22:12 martynas Exp $ */
2
3/*
4 * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <string.h>
20
21/*
22 * Reverse memchr()
23 * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
24 */
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
new file mode 100644
index 0000000000..ac5b7e90ad
--- /dev/null
+++ b/src/lib/libc/string/memset.3
@@ -0,0 +1,75 @@
1.\" $OpenBSD: memset.3,v 1.8 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt MEMSET 3
36.Os
37.Sh NAME
38.Nm memset
39.Nd write a byte to byte string
40.Sh SYNOPSIS
41.In string.h
42.Ft void *
43.Fn memset "void *b" "int c" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn memset
47function writes
48.Fa len
49bytes of value
50.Fa c
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
59.Fa b .
60.Sh SEE ALSO
61.Xr bzero 3 ,
62.Xr swab 3 ,
63.Xr wmemset 3
64.Sh STANDARDS
65The
66.Fn memset
67function conforms to
68.St -ansiC .
69.Sh HISTORY
70The
71.Fn memset
72function first appeared in
73.At V
74and was reimplemented for
75.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/memset.c b/src/lib/libc/string/memset.c
new file mode 100644
index 0000000000..61709c139d
--- /dev/null
+++ b/src/lib/libc/string/memset.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: memset.c,v 1.6 2008/03/15 21:40:39 ray Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36void *
37memset(void *dst, int c, size_t n)
38{
39 if (n != 0) {
40 unsigned char *d = dst;
41
42 do
43 *d++ = (unsigned char)c;
44 while (--n != 0);
45 }
46 return (dst);
47}
diff --git a/src/lib/libc/string/rindex.c b/src/lib/libc/string/rindex.c
new file mode 100644
index 0000000000..bf9d6f7cf1
--- /dev/null
+++ b/src/lib/libc/string/rindex.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: rindex.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <string.h>
32
33char *
34#ifdef STRRCHR
35strrchr(const char *p, int ch)
36#else
37rindex(const char *p, int ch)
38#endif
39{
40 char *save;
41
42 for (save = NULL;; ++p) {
43 if (*p == ch)
44 save = (char *)p;
45 if (!*p)
46 return(save);
47 }
48 /* NOTREACHED */
49}
diff --git a/src/lib/libc/string/stpcpy.3 b/src/lib/libc/string/stpcpy.3
new file mode 100644
index 0000000000..973eebecdd
--- /dev/null
+++ b/src/lib/libc/string/stpcpy.3
@@ -0,0 +1,184 @@
1.\" $OpenBSD: stpcpy.3,v 1.6 2014/02/23 23:09:34 schwarze Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: February 23 2014 $
35.Dt STPCPY 3
36.Os
37.Sh NAME
38.Nm stpcpy ,
39.Nm stpncpy
40.Nd copy strings
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn stpcpy "char *dst" "const char *src"
45.Ft char *
46.Fn stpncpy "char *dst" "const char *src" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn stpcpy
50and
51.Fn stpncpy
52functions copy the string
53.Fa src
54to
55.Fa dst
56(including the terminating
57.Ql \e0
58character).
59.Pp
60The
61.Fn stpncpy
62function copies not more than
63.Fa len
64characters into
65.Fa dst ,
66appending
67.Ql \e0
68characters if
69.Fa src
70is less than
71.Fa len
72characters long, and
73.Em not
74terminating
75.Fa dst
76if the length of
77.Fa src
78is greater than or equal to
79.Fa len .
80.Pp
81If the
82.Fa src
83and
84.Fa dst
85strings overlap, the behavior is undefined.
86.Sh RETURN VALUES
87The
88.Fn stpcpy
89function returns a pointer to the terminating
90.Ql \e0
91character written into
92.Fa dst .
93.Pp
94The
95.Fn stpncpy
96function returns a pointer to the first
97.Ql \e0
98character written into
99.Fa dst ,
100or to
101.Fa &dst[len]
102if the length of
103.Fa src
104is greater than or equal to
105.Fa len .
106.Sh EXAMPLES
107The most common use of
108.Fn stpcpy
109is to build up a string from multiple elements.
110The following example builds up a pathname from
111directory and file components using
112.Fn stpcpy :
113.Bd -literal -offset indent
114char *dir, *file, pname[PATH_MAX];
115
116\&...
117
118if (strlen(dir) + strlen("/") + strlen(file) >= sizeof(pname))
119 goto toolong;
120stpcpy(stpcpy(stpcpy(pname, dir), "/"), file);
121.Ed
122.Pp
123However, the size check required to avoid a buffer overflow is error
124prone since the check can become out of sync with the code that
125performs the copy.
126.Pp
127One might expect that
128.Fn stpncpy
129could be safely used instead, but it suffers from the same defects as
130.Fn strncpy .
131The example below using
132.Fn stpncpy
133is even more prone to error and will not detect when truncation occurs:
134.Bd -literal -offset indent
135char *dir, *file, pname[PATH_MAX];
136char *p1, *p2;
137
138\&...
139
140p1 = stpncpy(pname, dir, sizeof(pname) - 1);
141p2 = stpncpy(p1, "/", sizeof(pname) - 1 - (p1 - pname));
142stpncpy(p2, file, sizeof(pname) - 1 - (p2 - pname));
143pname[sizeof(pname) - 1] = '\e0';
144.Ed
145.Pp
146A safer (and simpler) approach is to use
147.Fn snprintf :
148.Bd -literal -offset indent
149char *dir, *file, pname[PATH_MAX];
150int len;
151
152\&...
153
154len = snprintf(pname, sizeof(pname), "%s/%s", dir, file);
155if (len >= sizeof(pname))
156 goto toolong;
157.Ed
158.Pp
159In most cases, it is better to use
160.Fn snprintf ,
161.Fn strlcpy ,
162or
163.Fn strlcat .
164.Sh SEE ALSO
165.Xr snprintf 3 ,
166.Xr strcpy 3 ,
167.Xr strlcpy 3 ,
168.Xr strncpy 3
169.Sh STANDARDS
170The
171.Fn stpcpy
172and
173.Fn stpncpy
174functions conform to
175.St -p1003.1-2008 .
176.Sh HISTORY
177The function
178.Fn stpcpy
179first appeared in the Lattice C AmigaDOS compiler (1986 or earlier).
180The function
181.Fn stpncpy
182first appeared in the GNU C library version 1.07 (1993).
183Both functions have been available since
184.Ox 5.1 .
diff --git a/src/lib/libc/string/stpcpy.c b/src/lib/libc/string/stpcpy.c
new file mode 100644
index 0000000000..d3d61e0f14
--- /dev/null
+++ b/src/lib/libc/string/stpcpy.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: stpcpy.c,v 1.1 2012/01/17 02:48:01 guenther Exp $ */
2
3/*
4 * Copyright (c) 1988 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 <string.h>
33
34#if defined(APIWARN)
35__warn_references(stpcpy,
36 "warning: stpcpy() is dangerous GNU crap; don't use it");
37#endif
38
39char *
40stpcpy(char *to, const char *from)
41{
42 for (; (*to = *from) != '\0'; ++from, ++to);
43 return(to);
44}
diff --git a/src/lib/libc/string/stpncpy.c b/src/lib/libc/string/stpncpy.c
new file mode 100644
index 0000000000..c7c2a57c4c
--- /dev/null
+++ b/src/lib/libc/string/stpncpy.c
@@ -0,0 +1,56 @@
1/* $OpenBSD: stpncpy.c,v 1.2 2012/07/11 10:44:59 naddy Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <string.h>
36
37char *
38stpncpy(char *dst, const char *src, size_t n)
39{
40 if (n != 0) {
41 char *d = dst;
42 const char *s = src;
43
44 dst = &dst[n];
45 do {
46 if ((*d++ = *s++) == 0) {
47 dst = d - 1;
48 /* NUL pad the remaining n-1 bytes */
49 while (--n != 0)
50 *d++ = 0;
51 break;
52 }
53 } while (--n != 0);
54 }
55 return (dst);
56}
diff --git a/src/lib/libc/string/strcasecmp.3 b/src/lib/libc/string/strcasecmp.3
new file mode 100644
index 0000000000..8bd7387dc5
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: strcasecmp.3,v 1.12 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRCASECMP 3
36.Os
37.Sh NAME
38.Nm strcasecmp ,
39.Nm strncasecmp
40.Nd compare strings, ignoring case
41.Sh SYNOPSIS
42.In string.h
43.Ft int
44.Fn strcasecmp "const char *s1" "const char *s2"
45.Ft int
46.Fn strncasecmp "const char *s1" "const char *s2" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn strcasecmp
50and
51.Fn strncasecmp
52functions compare the NUL-terminated strings
53.Fa s1
54and
55.Fa s2
56and return an integer greater than, equal to, or less than 0,
57according to whether
58.Fa s1
59is lexicographically greater than, equal to, or less than
60.Fa s2
61after translation of each corresponding character to lower-case.
62The strings themselves are not modified.
63The comparison is done using unsigned characters, so that
64.Sq Li \e200
65is greater than
66.Ql \e0 .
67.Pp
68.Fn strncasecmp
69compares at most
70.Fa len
71characters.
72.Sh SEE ALSO
73.Xr bcmp 3 ,
74.Xr memcmp 3 ,
75.Xr strcmp 3 ,
76.Xr strcoll 3 ,
77.Xr strxfrm 3 ,
78.Xr wcscasecmp 3
79.Sh STANDARDS
80The
81.Fn strcasecmp
82and
83.Fn strncasecmp
84functions conform to
85.St -p1003.1-2008 .
86.Sh HISTORY
87The
88.Fn strcasecmp
89and
90.Fn strncasecmp
91functions first appeared in
92.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strcasecmp.c b/src/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000000..2be09136c0
--- /dev/null
+++ b/src/lib/libc/string/strcasecmp.c
@@ -0,0 +1,105 @@
1/* $OpenBSD: strcasecmp.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1987, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. 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 <string.h>
33
34typedef unsigned char u_char;
35
36/*
37 * This array is designed for mapping upper and lower case letter
38 * together for a case independent comparison. The mappings are
39 * based upon ascii character sequences.
40 */
41static const u_char charmap[] = {
42 '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
43 '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
44 '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
45 '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
46 '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
47 '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
48 '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
49 '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
50 '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
51 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
52 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
53 '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
54 '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
55 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
56 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
57 '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
58 '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
59 '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
60 '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
61 '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
62 '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
63 '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
64 '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
65 '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
66 '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
67 '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
68 '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
69 '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
70 '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
71 '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
72 '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
73 '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
74};
75
76int
77strcasecmp(const char *s1, const char *s2)
78{
79 const u_char *cm = charmap;
80 const u_char *us1 = (const u_char *)s1;
81 const u_char *us2 = (const u_char *)s2;
82
83 while (cm[*us1] == cm[*us2++])
84 if (*us1++ == '\0')
85 return (0);
86 return (cm[*us1] - cm[*--us2]);
87}
88
89int
90strncasecmp(const char *s1, const char *s2, size_t n)
91{
92 if (n != 0) {
93 const u_char *cm = charmap;
94 const u_char *us1 = (const u_char *)s1;
95 const u_char *us2 = (const u_char *)s2;
96
97 do {
98 if (cm[*us1] != cm[*us2++])
99 return (cm[*us1] - cm[*--us2]);
100 if (*us1++ == '\0')
101 break;
102 } while (--n != 0);
103 }
104 return (0);
105}
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
new file mode 100644
index 0000000000..fba992edd9
--- /dev/null
+++ b/src/lib/libc/string/strcat.3
@@ -0,0 +1,81 @@
1.\" $OpenBSD: strcat.3,v 1.16 2013/12/19 20:52:37 millert Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: December 19 2013 $
35.Dt STRCAT 3
36.Os
37.Sh NAME
38.Nm strcat
39.Nd concatenate two strings
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strcat "char *s" "const char *append"
44.Sh DESCRIPTION
45The
46.Fn strcat
47function appends a copy of the NUL-terminated string
48.Fa append
49to the end of the NUL-terminated string
50.Fa s ,
51then adds a terminating
52.Ql \e0 .
53The string
54.Fa s
55must have sufficient space to hold the result.
56.Sh RETURN VALUES
57The
58.Fn strcat
59function return the pointer
60.Fa s .
61.Sh SEE ALSO
62.Xr bcopy 3 ,
63.Xr memccpy 3 ,
64.Xr memcpy 3 ,
65.Xr memmove 3 ,
66.Xr strcpy 3 ,
67.Xr strlcpy 3 ,
68.Xr strncat 3 ,
69.Xr wcscat 3 ,
70.Xr wcslcpy 3
71.Sh STANDARDS
72The
73.Fn strcat
74function conforms to
75.St -ansiC .
76.Sh HISTORY
77The
78.Fn strcat
79function first appeared in the Programmer's Workbench (PWB/UNIX)
80and was ported to
81.At v7 .
diff --git a/src/lib/libc/string/strcat.c b/src/lib/libc/string/strcat.c
new file mode 100644
index 0000000000..7cea5229fb
--- /dev/null
+++ b/src/lib/libc/string/strcat.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strcat.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1988 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#if !defined(_KERNEL) && !defined(_STANDALONE)
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
42
43char *
44strcat(char *s, const char *append)
45{
46 char *save = s;
47
48 for (; *s; ++s);
49 while ((*s++ = *append++) != '\0');
50 return(save);
51}
diff --git a/src/lib/libc/string/strchr.3 b/src/lib/libc/string/strchr.3
new file mode 100644
index 0000000000..eb9ac8e833
--- /dev/null
+++ b/src/lib/libc/string/strchr.3
@@ -0,0 +1,114 @@
1.\" $OpenBSD: strchr.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRCHR 3
36.Os
37.Sh NAME
38.Nm strchr ,
39.Nm index
40.Nd locate first occurrence of a character in a string
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn strchr "const char *s" "int c"
45.Ft char *
46.Fn index "const char *s" "int c"
47.Sh DESCRIPTION
48The
49.Fn strchr
50function locates the first occurrence of the character
51.Fa c
52in the string
53.Fa s .
54The terminating NUL character is considered part of the string.
55If
56.Fa c
57is
58.Ql \e0 ,
59.Fn strchr
60locates the terminating
61.Ql \e0 .
62.Pp
63The
64.Fn index
65function is an old synonym for
66.Fn strchr .
67.Sh RETURN VALUES
68The
69.Fn strchr
70function returns a pointer to the located character or
71.Dv NULL
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
85.Sh SEE ALSO
86.Xr memchr 3 ,
87.Xr strcspn 3 ,
88.Xr strpbrk 3 ,
89.Xr strrchr 3 ,
90.Xr strsep 3 ,
91.Xr strspn 3 ,
92.Xr strstr 3 ,
93.Xr strtok 3 ,
94.Xr wcschr 3
95.Sh STANDARDS
96The
97.Fn strchr
98function conforms to
99.St -ansiC .
100.Pp
101The
102.Fn index
103function is deprecated and shouldn't be used in new code.
104.Sh HISTORY
105The
106.Fn index
107function first appeared in
108.At v7 .
109The
110.Fn strchr
111function first appeared in
112.At III
113and was reimplemented for
114.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strcmp.3 b/src/lib/libc/string/strcmp.3
new file mode 100644
index 0000000000..63dc7fed2d
--- /dev/null
+++ b/src/lib/libc/string/strcmp.3
@@ -0,0 +1,97 @@
1.\" $OpenBSD: strcmp.3,v 1.14 2013/07/17 05:42:11 schwarze Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt STRCMP 3
36.Os
37.Sh NAME
38.Nm strcmp ,
39.Nm strncmp
40.Nd compare strings
41.Sh SYNOPSIS
42.In string.h
43.Ft int
44.Fn strcmp "const char *s1" "const char *s2"
45.Ft int
46.Fn strncmp "const char *s1" "const char *s2" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn strcmp
50and
51.Fn strncmp
52functions lexicographically compare the NUL-terminated strings
53.Fa s1
54and
55.Fa s2 .
56The
57.Fn strncmp
58function compares at most
59.Fa len
60characters.
61.Sh RETURN VALUES
62The
63.Fn strcmp
64and
65.Fn strncmp
66functions return an integer greater than, equal to, or less than 0, according
67to whether the string
68.Fa s1
69is greater than, equal to, or less than the string
70.Fa s2 .
71The comparison is done using unsigned characters, so that
72.Ql \e200
73is greater than
74.Ql \e0 .
75.Sh SEE ALSO
76.Xr bcmp 3 ,
77.Xr memcmp 3 ,
78.Xr strcasecmp 3 ,
79.Xr strcoll 3 ,
80.Xr strxfrm 3 ,
81.Xr wcscmp 3
82.Sh STANDARDS
83The
84.Fn strcmp
85and
86.Fn strncmp
87functions conform to
88.St -ansiC .
89.Sh HISTORY
90The
91.Fn strcmp
92function first appeared in the Programmer's Workbench (PWB/UNIX)
93and was ported to
94.At v7 ;
95.Fn strncmp
96first appeared in
97.At v7 .
diff --git a/src/lib/libc/string/strcmp.c b/src/lib/libc/string/strcmp.c
new file mode 100644
index 0000000000..816fd111ac
--- /dev/null
+++ b/src/lib/libc/string/strcmp.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strcmp.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if !defined(_KERNEL) && !defined(_STANDALONE)
36#include <string.h>
37#else
38#include <lib/libkern/libkern.h>
39#endif
40
41/*
42 * Compare strings.
43 */
44int
45strcmp(const char *s1, const char *s2)
46{
47 while (*s1 == *s2++)
48 if (*s1++ == 0)
49 return (0);
50 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
51}
diff --git a/src/lib/libc/string/strcoll.3 b/src/lib/libc/string/strcoll.3
new file mode 100644
index 0000000000..d421200b62
--- /dev/null
+++ b/src/lib/libc/string/strcoll.3
@@ -0,0 +1,73 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strcoll.3,v 1.9 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRCOLL 3
36.Os
37.Sh NAME
38.Nm strcoll
39.Nd compare strings according to current collation
40.Sh SYNOPSIS
41.In string.h
42.Ft int
43.Fn strcoll "const char *s1" "const char *s2"
44.Sh DESCRIPTION
45The
46.Fn strcoll
47function lexicographically compares the NUL-terminated strings
48.Fa s1
49and
50.Fa s2
51according to the current locale collation
52and returns an integer greater than, equal to, or less than 0,
53according to whether
54.Fa s1
55is greater than, equal to, or less than
56.Fa s2 .
57.Sh SEE ALSO
58.Xr bcmp 3 ,
59.Xr memcmp 3 ,
60.Xr setlocale 3 ,
61.Xr strcasecmp 3 ,
62.Xr strcmp 3 ,
63.Xr strxfrm 3
64.Sh STANDARDS
65The
66.Fn strcoll
67function conforms to
68.St -ansiC .
69.Sh HISTORY
70The
71.Fn strcoll
72function first appeared in
73.Bx 4.3 Reno .
diff --git a/src/lib/libc/string/strcoll.c b/src/lib/libc/string/strcoll.c
new file mode 100644
index 0000000000..2df983bd65
--- /dev/null
+++ b/src/lib/libc/string/strcoll.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: strcoll.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Compare strings according to LC_COLLATE category of current locale.
38 */
39int
40strcoll(const char *s1, const char *s2)
41{
42 /* LC_COLLATE is unimplemented, hence always "C" */
43 return (strcmp(s1, s2));
44}
diff --git a/src/lib/libc/string/strcpy.3 b/src/lib/libc/string/strcpy.3
new file mode 100644
index 0000000000..849184d1f5
--- /dev/null
+++ b/src/lib/libc/string/strcpy.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: strcpy.3,v 1.20 2013/12/19 20:52:37 millert Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: December 19 2013 $
35.Dt STRCPY 3
36.Os
37.Sh NAME
38.Nm strcpy
39.Nd copy a string
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strcpy "char *dst" "const char *src"
44.Sh DESCRIPTION
45The
46.Fn strcpy
47function copies the string
48.Fa src
49to
50.Fa dst
51(including the terminating
52.Ql \e0
53character).
54The string
55.Fa dst
56must be at least as large as
57.Fa src
58to hold the result.
59.Pp
60If the
61.Fa src
62and
63.Fa dst
64strings overlap, the behavior is undefined.
65.Sh RETURN VALUES
66The
67.Fn strcpy
68function returns
69.Fa dst .
70.Sh SEE ALSO
71.Xr bcopy 3 ,
72.Xr memccpy 3 ,
73.Xr memcpy 3 ,
74.Xr memmove 3 ,
75.Xr strcat 3 ,
76.Xr strlcpy 3 ,
77.Xr strncpy 3 ,
78.Xr wcscpy 3 ,
79.Xr wcslcpy 3
80.Sh STANDARDS
81The
82.Fn strcpy
83and
84.Fn strncpy
85functions conform to
86.St -ansiC .
87.Sh HISTORY
88The
89.Fn strcpy
90function first appeared in the Programmer's Workbench (PWB/UNIX)
91and was ported to
92.At v7 .
diff --git a/src/lib/libc/string/strcpy.c b/src/lib/libc/string/strcpy.c
new file mode 100644
index 0000000000..71d90d4100
--- /dev/null
+++ b/src/lib/libc/string/strcpy.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: strcpy.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1988 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#if !defined(_KERNEL) && !defined(_STANDALONE)
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
42
43char *
44strcpy(char *to, const char *from)
45{
46 char *save = to;
47
48 for (; (*to = *from) != '\0'; ++from, ++to);
49 return(save);
50}
diff --git a/src/lib/libc/string/strcspn.3 b/src/lib/libc/string/strcspn.3
new file mode 100644
index 0000000000..07eb9ca26f
--- /dev/null
+++ b/src/lib/libc/string/strcspn.3
@@ -0,0 +1,108 @@
1.\" $OpenBSD: strcspn.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRCSPN 3
36.Os
37.Sh NAME
38.Nm strcspn
39.Nd span the complement of a string
40.Sh SYNOPSIS
41.In string.h
42.Ft size_t
43.Fn strcspn "const char *s" "const char *charset"
44.Sh DESCRIPTION
45The
46.Fn strcspn
47function spans the initial part of the NUL-terminated string
48.Fa s
49as long as the characters from
50.Fa s
51do not occur in string
52.Fa charset
53(it spans the
54.Em complement
55of
56.Fa charset ) .
57.Sh RETURN VALUES
58The
59.Fn strcspn
60function returns 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
87.Sh SEE ALSO
88.Xr memchr 3 ,
89.Xr strchr 3 ,
90.Xr strpbrk 3 ,
91.Xr strrchr 3 ,
92.Xr strsep 3 ,
93.Xr strspn 3 ,
94.Xr strstr 3 ,
95.Xr strtok 3 ,
96.Xr wcscspn 3
97.Sh STANDARDS
98The
99.Fn strcspn
100function conforms to
101.St -ansiC .
102.Sh HISTORY
103The
104.Fn strcspn
105function first appeared in
106.At III
107and was reimplemented for
108.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strcspn.c b/src/lib/libc/string/strcspn.c
new file mode 100644
index 0000000000..1eb233614d
--- /dev/null
+++ b/src/lib/libc/string/strcspn.c
@@ -0,0 +1,58 @@
1/* $OpenBSD: strcspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Span the complement of string s2.
38 */
39size_t
40strcspn(const char *s1, const char *s2)
41{
42 const char *p, *spanp;
43 char c, sc;
44
45 /*
46 * Stop as soon as we find any character from s2. Note that there
47 * must be a NUL in s2; it suffices to stop when we find that, too.
48 */
49 for (p = s1;;) {
50 c = *p++;
51 spanp = s2;
52 do {
53 if ((sc = *spanp++) == c)
54 return (p - 1 - s1);
55 } while (sc != 0);
56 }
57 /* NOTREACHED */
58}
diff --git a/src/lib/libc/string/strdup.3 b/src/lib/libc/string/strdup.3
new file mode 100644
index 0000000000..2d7fa0bb96
--- /dev/null
+++ b/src/lib/libc/string/strdup.3
@@ -0,0 +1,112 @@
1.\" $OpenBSD: strdup.3,v 1.20 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt STRDUP 3
34.Os
35.Sh NAME
36.Nm strdup ,
37.Nm strndup
38.Nd save a copy of a string
39.Sh SYNOPSIS
40.In string.h
41.Ft char *
42.Fn strdup "const char *s"
43.Ft char *
44.Fn strndup "const char *s" "size_t maxlen"
45.Sh DESCRIPTION
46The
47.Fn strdup
48function allocates sufficient memory for a copy of the string
49.Fa s ,
50does the copy, and returns a pointer to it.
51The pointer may subsequently be used as an argument to the function
52.Xr free 3 .
53.Pp
54The
55.Fn strndup
56function behaves similarly to
57.Nm strdup
58but only copies up to
59.Fa maxlen
60characters from
61.Fa s .
62The resulting string is always NUL-terminated.
63.Pp
64If insufficient memory is available,
65.Dv NULL
66is returned.
67.Sh EXAMPLES
68The following will point
69.Va p
70to an allocated area of memory containing the NUL-terminated string
71.Qq foobar :
72.Bd -literal -offset indent
73char *p;
74
75p = strdup("foobar");
76if (p == NULL)
77 err(1, NULL);
78.Ed
79.Sh ERRORS
80The
81.Fn strdup
82and
83.Fn strndup
84functions may fail and set the external variable
85.Va errno
86for any of the errors specified for the library function
87.Xr malloc 3 .
88.Sh SEE ALSO
89.Xr free 3 ,
90.Xr malloc 3 ,
91.Xr strcpy 3 ,
92.Xr strlcpy 3 ,
93.Xr strlen 3 ,
94.Xr wcsdup 3
95.Sh STANDARDS
96The
97.Fn strdup
98and
99.Fn strndup
100functions conform to
101.St -p1003.1-2008 .
102.Sh HISTORY
103The
104.Fn strdup
105function first appeared in
106.Bx 4.3 Reno .
107The
108.Fn strndup
109function appeared in glibc 2.0, was reimplemented for
110.Nx 4.0 ,
111and ported to
112.Ox 4.8 .
diff --git a/src/lib/libc/string/strdup.c b/src/lib/libc/string/strdup.c
new file mode 100644
index 0000000000..a6aa1e03b0
--- /dev/null
+++ b/src/lib/libc/string/strdup.c
@@ -0,0 +1,49 @@
1/* $OpenBSD: strdup.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. 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/types.h>
33
34#include <stddef.h>
35#include <stdlib.h>
36#include <string.h>
37
38char *
39strdup(const char *str)
40{
41 size_t siz;
42 char *copy;
43
44 siz = strlen(str) + 1;
45 if ((copy = malloc(siz)) == NULL)
46 return(NULL);
47 (void)memcpy(copy, str, siz);
48 return(copy);
49}
diff --git a/src/lib/libc/string/strerror.3 b/src/lib/libc/string/strerror.3
new file mode 100644
index 0000000000..264ac39052
--- /dev/null
+++ b/src/lib/libc/string/strerror.3
@@ -0,0 +1,123 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strerror.3,v 1.13 2014/04/07 17:57:56 schwarze Exp $
33.\"
34.Dd $Mdocdate: April 7 2014 $
35.Dt STRERROR 3
36.Os
37.Sh NAME
38.Nm strerror ,
39.Nm strerror_r
40.Nd get error message string
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn strerror "int errnum"
45.Ft int
46.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
47.Sh DESCRIPTION
48The
49.Fn strerror
50and
51.Fn strerror_r
52functions map the error number
53.Fa errnum
54to a language-dependent error message string.
55.Pp
56.Fn strerror
57returns a string containing a maximum of
58.Dv NL_TEXTMAX
59characters, including the trailing NUL.
60This string is not to be modified by the calling program,
61but may be overwritten by subsequent calls to
62.Fn strerror .
63.Pp
64.Fn strerror_r
65is a thread safe version of
66.Fn strerror
67that places the error message in the specified buffer
68.Fa strerrbuf .
69.Sh RETURN VALUES
70.Fn strerror
71returns a pointer to the error message string.
72If an error occurs, the error code is stored in
73.Va errno .
74.Pp
75.Fn strerror_r
76returns zero upon successful completion.
77If an error occurs, the error code is stored in
78.Va errno
79and the error code is returned.
80.Sh ERRORS
81.Fn strerror
82and
83.Fn strerror_r
84may fail if:
85.Bl -tag -width Er
86.It Bq Er EINVAL
87.Fa errnum
88is not a valid error number.
89The returned error string will consist of an error message that includes
90.Fa errnum .
91.El
92.Pp
93.Fn strerror_r
94may fail if:
95.Bl -tag -width Er
96.It Bq Er ERANGE
97The error message is larger than
98.Fa buflen
99characters.
100The message will be truncated to fit.
101.El
102.Sh SEE ALSO
103.Xr intro 2 ,
104.Xr perror 3 ,
105.Xr setlocale 3
106.Sh STANDARDS
107The
108.Fn strerror
109function conforms to
110.St -ansiC-99 .
111The
112.Fn strerror_r
113function conforms to
114.St -p1003.1-2008 .
115.Sh HISTORY
116The
117.Fn strerror
118function first appeared in
119.Bx 4.3 Reno .
120The
121.Fn strerror_r
122function first appeared in
123.Ox 3.3 .
diff --git a/src/lib/libc/string/strerror.c b/src/lib/libc/string/strerror.c
new file mode 100644
index 0000000000..13996f08e9
--- /dev/null
+++ b/src/lib/libc/string/strerror.c
@@ -0,0 +1,41 @@
1/* $OpenBSD: strerror.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <string.h>
32#include <limits.h>
33
34char *
35strerror(int num)
36{
37 static char buf[NL_TEXTMAX];
38
39 (void)strerror_r(num, buf, sizeof(buf));
40 return (buf);
41}
diff --git a/src/lib/libc/string/strerror_r.c b/src/lib/libc/string/strerror_r.c
new file mode 100644
index 0000000000..b85136055b
--- /dev/null
+++ b/src/lib/libc/string/strerror_r.c
@@ -0,0 +1,137 @@
1/* $OpenBSD: strerror_r.c,v 1.8 2013/06/01 21:26:18 stsp Exp $ */
2/* Public Domain <marc@snafu.org> */
3
4#ifdef NLS
5#define catclose _catclose
6#define catgets _catgets
7#define catopen _catopen
8#include <nl_types.h>
9#endif
10
11#define sys_errlist _sys_errlist
12#define sys_nerr _sys_nerr
13#define sys_siglist _sys_siglist
14
15#include <errno.h>
16#include <limits.h>
17#include <signal.h>
18#include <string.h>
19
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", NL_CAT_LOCALE);
79#endif
80
81 if (0 <= num && num < max) {
82#ifdef NLS
83 len = strlcpy(buf, catgets(catd, setid, num, list[num]),
84 buflen);
85#else
86 len = strlcpy(buf, list[num], buflen);
87#endif
88 if (len >= buflen)
89 ret = ERANGE;
90 } else {
91#ifdef NLS
92 len = strlcpy(buf, catgets(catd, setid, 0xffff, def), buflen);
93#else
94 len = strlcpy(buf, def, buflen);
95#endif
96 if (len >= buflen)
97 ret = ERANGE;
98 else {
99 ret = __itoa(num, sign, buf, len, buflen);
100 if (ret == 0)
101 ret = EINVAL;
102 }
103 }
104
105#ifdef NLS
106 catclose(catd);
107#endif
108
109 return ret;
110}
111
112#define UPREFIX "Unknown error: "
113
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/string.3 b/src/lib/libc/string/string.3
new file mode 100644
index 0000000000..2373d1fb9c
--- /dev/null
+++ b/src/lib/libc/string/string.3
@@ -0,0 +1,136 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek.
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. 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.\" $OpenBSD: string.3,v 1.13 2013/06/05 03:39:23 tedu Exp $
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt STRING 3
34.Os
35.Sh NAME
36.Nm string
37.Nd string specific functions
38.Sh SYNOPSIS
39.In string.h
40.Ft char *
41.Fn strcat "char *s" "const char *append"
42.Ft char *
43.Fn strlcat "char *s" "const char *append" "size_t size"
44.Ft char *
45.Fn strncat "char *s" "const char *append" "size_t count"
46.Ft char *
47.Fn strchr "const char *s" "int c"
48.Ft char *
49.Fn strrchr "const char *s" "int c"
50.Ft int
51.Fn strcmp "const char *s1" "const char *s2"
52.Ft int
53.Fn strncmp "const char *s1" "const char *s2" "size_t count"
54.Ft int
55.Fn strcasecmp "const char *s1" "const char *s2"
56.Ft int
57.Fn strncasecmp "const char *s1" "const char *s2" "size_t count"
58.Ft char *
59.Fn strcpy "char *dst" "const char *src"
60.Ft char *
61.Fn strlcpy "char *dst" "const char *src" "size_t size"
62.Ft char *
63.Fn strncpy "char *dst" "const char *src" "size_t count"
64.Ft char *
65.Fn strerror "int errno"
66.Ft size_t
67.Fn strlen "const char *s"
68.Ft char *
69.Fn strpbrk "const char *s" "const char *charset"
70.Ft char *
71.Fn strsep "char **stringp" "const char *delim"
72.Ft size_t
73.Fn strspn "const char *s" "const char *charset"
74.Ft size_t
75.Fn strcspn "const char *s" "const char *charset"
76.Ft char *
77.Fn strstr "const char *big" "const char *little"
78.Ft char *
79.Fn strtok "char *s" "const char *delim"
80.Ft char *
81.Fn index "const char *s" "int c"
82.Ft char *
83.Fn rindex "const char *s" "int c"
84.Sh DESCRIPTION
85The string functions
86manipulate strings terminated by a
87NUL byte.
88.Pp
89See the specific manual pages for more information.
90For manipulating variable length generic objects as byte
91strings (without the NUL-byte check), see
92.Xr bstring 3 .
93.Pp
94Except as noted in their specific manual pages,
95the string functions do not test the destination
96for size limitations.
97.Sh SEE ALSO
98.Xr bstring 3 ,
99.Xr index 3 ,
100.Xr rindex 3 ,
101.Xr strcasecmp 3 ,
102.Xr strcat 3 ,
103.Xr strchr 3 ,
104.Xr strcmp 3 ,
105.Xr strcpy 3 ,
106.Xr strcspn 3 ,
107.Xr strerror 3 ,
108.Xr strlcat 3 ,
109.Xr strlcpy 3 ,
110.Xr strlen 3 ,
111.Xr strpbrk 3 ,
112.Xr strrchr 3 ,
113.Xr strsep 3 ,
114.Xr strspn 3 ,
115.Xr strstr 3 ,
116.Xr strtok 3
117.Sh STANDARDS
118The
119.Fn strcat ,
120.Fn strncat ,
121.Fn strchr ,
122.Fn strrchr ,
123.Fn strcmp ,
124.Fn strncmp ,
125.Fn strcpy ,
126.Fn strncpy ,
127.Fn strerror ,
128.Fn strlen ,
129.Fn strpbrk ,
130.Fn strspn ,
131.Fn strcspn ,
132.Fn strstr ,
133and
134.Fn strtok
135functions conform to
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..044c959c0c
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,188 @@
1.\" $OpenBSD: strlcpy.3,v 1.26 2013/09/30 12:02:35 millert Exp $
2.\"
3.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: September 30 2013 $
18.Dt STRLCPY 3
19.Os
20.Sh NAME
21.Nm strlcpy ,
22.Nm strlcat
23.Nd size-bounded string copying and concatenation
24.Sh SYNOPSIS
25.In string.h
26.Ft size_t
27.Fn strlcpy "char *dst" "const char *src" "size_t dstsize"
28.Ft size_t
29.Fn strlcat "char *dst" "const char *src" "size_t dstsize"
30.Sh DESCRIPTION
31The
32.Fn strlcpy
33and
34.Fn strlcat
35functions copy and concatenate strings with the
36same input parameters and output result as
37.Xr snprintf 3 .
38They are designed to be safer, more consistent, and less error
39prone replacements for the easily misused functions
40.Xr strncpy 3
41and
42.Xr strncat 3 .
43.Pp
44.Fn strlcpy
45and
46.Fn strlcat
47take the full size of the destination buffer and guarantee
48NUL-termination if there is room.
49Note that room for the NUL should be included in
50.Fa dstsize .
51.Pp
52.Fn strlcpy
53copies up to
54.Fa dstsize
55\- 1 characters from the string
56.Fa src
57to
58.Fa dst ,
59NUL-terminating the result if
60.Fa dstsize
61is not 0.
62.Pp
63.Fn strlcat
64appends string
65.Fa src
66to the end of
67.Fa dst .
68It will append at most
69.Fa dstsize
70\- strlen(dst) \- 1 characters.
71It will then NUL-terminate, unless
72.Fa dstsize
73is 0 or the original
74.Fa dst
75string was longer than
76.Fa dstsize
77(in practice this should not happen
78as it means that either
79.Fa dstsize
80is incorrect or that
81.Fa dst
82is not a proper string).
83.Pp
84If the
85.Fa src
86and
87.Fa dst
88strings overlap, the behavior is undefined.
89.Sh RETURN VALUES
90Besides quibbles over the return type
91.Pf ( Va size_t
92versus
93.Va int )
94and signal handler safety
95.Pf ( Xr snprintf 3
96is not entirely safe on some systems), the
97following two are equivalent:
98.Bd -literal -offset indent
99n = strlcpy(dst, src, len);
100n = snprintf(dst, len, "%s", src);
101.Ed
102.Pp
103Like
104.Xr snprintf 3 ,
105the
106.Fn strlcpy
107and
108.Fn strlcat
109functions return the total length of the string they tried to create.
110For
111.Fn strlcpy
112that means the length of
113.Fa src .
114For
115.Fn strlcat
116that means the initial length of
117.Fa dst
118plus
119the length of
120.Fa src .
121.Pp
122If the return value is
123.Cm >=
124.Va dstsize ,
125the output string has been truncated.
126It is the caller's responsibility to handle this.
127.Sh EXAMPLES
128The following code fragment illustrates the simple case:
129.Bd -literal -offset indent
130char *s, *p, buf[BUFSIZ];
131
132\&...
133
134(void)strlcpy(buf, s, sizeof(buf));
135(void)strlcat(buf, p, sizeof(buf));
136.Ed
137.Pp
138To detect truncation, perhaps while building a pathname, something
139like the following might be used:
140.Bd -literal -offset indent
141char *dir, *file, pname[PATH_MAX];
142
143\&...
144
145if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
146 goto toolong;
147if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
148 goto toolong;
149.Ed
150.Pp
151Since it is known how many characters were copied the first time, things
152can be sped up a bit by using a copy instead of an append:
153.Bd -literal -offset indent
154char *dir, *file, pname[PATH_MAX];
155size_t n;
156
157\&...
158
159n = strlcpy(pname, dir, sizeof(pname));
160if (n >= sizeof(pname))
161 goto toolong;
162if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
163 goto toolong;
164.Ed
165.Pp
166However, one may question the validity of such optimizations, as they
167defeat the whole purpose of
168.Fn strlcpy
169and
170.Fn strlcat .
171As a matter of fact, the first version of this manual page got it wrong.
172.Sh SEE ALSO
173.Xr snprintf 3 ,
174.Xr strncat 3 ,
175.Xr strncpy 3 ,
176.Xr wcslcpy 3
177.Sh HISTORY
178.Fn strlcpy
179and
180.Fn strlcat
181first appeared in
182.Ox 2.4 .
183.Sh AUTHORS
184.Fn strlcpy
185and
186.Fn strlcat
187were created by
188.An Todd C. Miller Aq Mt Todd.Miller@courtesan.com .
diff --git a/src/lib/libc/string/strlcpy.c b/src/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000000..d32b6590f1
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <string.h>
21
22/*
23 * Copy src to string dst of size siz. At most siz-1 characters
24 * will be copied. Always NUL terminates (unless siz == 0).
25 * Returns strlen(src); if retval >= siz, truncation occurred.
26 */
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
new file mode 100644
index 0000000000..5428627abb
--- /dev/null
+++ b/src/lib/libc/string/strlen.3
@@ -0,0 +1,105 @@
1.\" $OpenBSD: strlen.3,v 1.12 2013/07/17 05:42:11 schwarze Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: July 17 2013 $
35.Dt STRLEN 3
36.Os
37.Sh NAME
38.Nm strlen ,
39.Nm strnlen
40.Nd find length of a string
41.Sh SYNOPSIS
42.In string.h
43.Ft size_t
44.Fn strlen "const char *s"
45.Ft size_t
46.Fn strnlen "const char *s" "size_t maxlen"
47.Sh DESCRIPTION
48The
49.Fn strlen
50function computes the length of the string
51.Fa s .
52.Pp
53The
54.Fn strnlen
55function computes the length of the string
56.Fa s ,
57up to
58.Fa maxlen
59characters.
60The
61.Fn strnlen
62function will never attempt to address more than
63.Fa maxlen
64characters, making it suitable for use with character arrays that are
65not guaranteed to be NUL-terminated.
66.Sh RETURN VALUES
67The
68.Fn strlen
69function returns the number of characters that precede the terminating
70.Tn NUL
71character.
72.Pp
73The
74.Fn strnlen
75function returns the number of characters that precede the terminating
76.Tn NUL
77or
78.Fa maxlen ,
79whichever is smaller.
80.Sh SEE ALSO
81.Xr string 3 ,
82.Xr wcslen 3
83.Sh STANDARDS
84The
85.Fn strlen
86function conforms to
87.St -ansiC .
88.Pp
89The
90.Fn strlen
91and
92.Fn strnlen
93functions conform to
94.St -p1003.1-2008 .
95.Sh HISTORY
96The
97.Fn strlen
98function first appeared in the Programmer's Workbench (PWB/UNIX)
99and was ported to
100.At v7 .
101The
102.Fn strnlen
103function appeared in glibc 2.0
104and was reimplemented for
105.Ox 4.8 .
diff --git a/src/lib/libc/string/strlen.c b/src/lib/libc/string/strlen.c
new file mode 100644
index 0000000000..12d9ec4dad
--- /dev/null
+++ b/src/lib/libc/string/strlen.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: strlen.c,v 1.7 2005/08/08 08:05:37 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#if !defined(_KERNEL) && !defined(_STANDALONE)
33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
37
38size_t
39strlen(const char *str)
40{
41 const char *s;
42
43 for (s = str; *s; ++s)
44 ;
45 return (s - str);
46}
47
diff --git a/src/lib/libc/string/strmode.3 b/src/lib/libc/string/strmode.3
new file mode 100644
index 0000000000..bebda2ca1c
--- /dev/null
+++ b/src/lib/libc/string/strmode.3
@@ -0,0 +1,157 @@
1.\" $OpenBSD: strmode.3,v 1.16 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\" may be used to endorse or promote products derived from this software
16.\" without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.\" @(#)strmode.3 8.3 (Berkeley) 7/28/94
31.\"
32.Dd $Mdocdate: June 5 2013 $
33.Dt STRMODE 3
34.Os
35.Sh NAME
36.Nm strmode
37.Nd convert inode status information into a symbolic string
38.Sh SYNOPSIS
39.In string.h
40.Ft void
41.Fn strmode "mode_t mode" "char *bp"
42.Sh DESCRIPTION
43The
44.Fn strmode
45function converts a file
46.Fa mode
47(the type and permission information associated with an inode, see
48.Xr stat 2 )
49into a symbolic string which is stored in the location referenced by
50.Fa bp .
51This stored string is eleven characters in length plus a trailing NUL byte.
52.Pp
53The first character is the inode type, and will be one of the following:
54.Pp
55.Bl -tag -width flag -offset indent -compact
56.It \-
57regular file
58.It b
59block special
60.It c
61character special
62.It d
63directory
64.It l
65symbolic link
66.It p
67FIFO
68.It s
69socket
70.It \&?
71unknown inode type
72.El
73.Pp
74The next nine characters encode three sets of permissions, in three
75characters each.
76The first three characters are the permissions for the owner of the
77file, the second three for the group the file belongs to, and the
78third for the
79.Dq other ,
80or default, set of users.
81.Pp
82Permission checking is done as specifically as possible.
83If read permission is denied to the owner of a file in the first set
84of permissions, the owner of the file will not be able to read the file.
85This is true even if the owner is in the file's group and the group
86permissions allow reading or the
87.Dq other
88permissions allow reading.
89.Pp
90If the first character of the three character set is an
91.Sq r ,
92the file is readable for that set of users; if a dash
93.Pq Ql - ,
94it is not readable.
95.Pp
96If the second character of the three character set is a
97.Sq w ,
98the file is writable for that set of users; if a dash
99.Pq Ql - ,
100it is not writable.
101.Pp
102The third character is the first of the following characters that apply:
103.Bl -tag -width xxxx
104.It S
105If the character is part of the owner permissions and the file is not
106executable or the directory is not searchable by the owner, and the
107set-user-ID bit is set.
108.It S
109If the character is part of the group permissions and the file is not
110executable or the directory is not searchable by the group, and the
111set-group-ID bit is set.
112.It T
113If the character is part of the other permissions and the file is not
114executable or the directory is not searchable by others, and the
115.Dq sticky
116.Pq Dv S_ISVTX
117bit is set.
118.It s
119If the character is part of the owner permissions and the file is
120executable or the directory searchable by the owner, and the set-user-ID
121bit is set.
122.It s
123If the character is part of the group permissions and the file is
124executable or the directory searchable by the group, and the set-group-ID
125bit is set.
126.It t
127If the character is part of the other permissions and the file is
128executable or the directory searchable by others, and the
129.Dq sticky
130.Pq Dv S_ISVTX
131bit is set.
132.It x
133The file is executable or the directory is searchable.
134.It \-
135None of the above apply.
136.El
137.Pp
138The last character is a plus sign
139.Pq Ql +
140if there are any alternate
141or additional access control methods associated with the inode, otherwise
142it will be a space.
143.Sh RETURN VALUES
144The
145.Fn strmode
146function always returns 0.
147.Sh SEE ALSO
148.Xr chmod 1 ,
149.Xr find 1 ,
150.Xr stat 2 ,
151.Xr getmode 3 ,
152.Xr setmode 3
153.Sh HISTORY
154The
155.Fn strmode
156function first appeared in
157.Bx 4.3 Reno .
diff --git a/src/lib/libc/string/strmode.c b/src/lib/libc/string/strmode.c
new file mode 100644
index 0000000000..6f0fa34ed8
--- /dev/null
+++ b/src/lib/libc/string/strmode.c
@@ -0,0 +1,140 @@
1/* $OpenBSD: strmode.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <string.h>
34
35/* XXX mode should be mode_t */
36
37void
38strmode(int mode, char *p)
39{
40 /* print type */
41 switch (mode & S_IFMT) {
42 case S_IFDIR: /* directory */
43 *p++ = 'd';
44 break;
45 case S_IFCHR: /* character special */
46 *p++ = 'c';
47 break;
48 case S_IFBLK: /* block special */
49 *p++ = 'b';
50 break;
51 case S_IFREG: /* regular */
52 *p++ = '-';
53 break;
54 case S_IFLNK: /* symbolic link */
55 *p++ = 'l';
56 break;
57 case S_IFSOCK: /* socket */
58 *p++ = 's';
59 break;
60#ifdef S_IFIFO
61 case S_IFIFO: /* fifo */
62 *p++ = 'p';
63 break;
64#endif
65 default: /* unknown */
66 *p++ = '?';
67 break;
68 }
69 /* usr */
70 if (mode & S_IRUSR)
71 *p++ = 'r';
72 else
73 *p++ = '-';
74 if (mode & S_IWUSR)
75 *p++ = 'w';
76 else
77 *p++ = '-';
78 switch (mode & (S_IXUSR | S_ISUID)) {
79 case 0:
80 *p++ = '-';
81 break;
82 case S_IXUSR:
83 *p++ = 'x';
84 break;
85 case S_ISUID:
86 *p++ = 'S';
87 break;
88 case S_IXUSR | S_ISUID:
89 *p++ = 's';
90 break;
91 }
92 /* group */
93 if (mode & S_IRGRP)
94 *p++ = 'r';
95 else
96 *p++ = '-';
97 if (mode & S_IWGRP)
98 *p++ = 'w';
99 else
100 *p++ = '-';
101 switch (mode & (S_IXGRP | S_ISGID)) {
102 case 0:
103 *p++ = '-';
104 break;
105 case S_IXGRP:
106 *p++ = 'x';
107 break;
108 case S_ISGID:
109 *p++ = 'S';
110 break;
111 case S_IXGRP | S_ISGID:
112 *p++ = 's';
113 break;
114 }
115 /* other */
116 if (mode & S_IROTH)
117 *p++ = 'r';
118 else
119 *p++ = '-';
120 if (mode & S_IWOTH)
121 *p++ = 'w';
122 else
123 *p++ = '-';
124 switch (mode & (S_IXOTH | S_ISVTX)) {
125 case 0:
126 *p++ = '-';
127 break;
128 case S_IXOTH:
129 *p++ = 'x';
130 break;
131 case S_ISVTX:
132 *p++ = 'T';
133 break;
134 case S_IXOTH | S_ISVTX:
135 *p++ = 't';
136 break;
137 }
138 *p++ = ' '; /* will be a '+' if ACL's implemented */
139 *p = '\0';
140}
diff --git a/src/lib/libc/string/strncat.3 b/src/lib/libc/string/strncat.3
new file mode 100644
index 0000000000..bd15ef10fa
--- /dev/null
+++ b/src/lib/libc/string/strncat.3
@@ -0,0 +1,128 @@
1.\" $OpenBSD: strncat.3,v 1.2 2013/12/19 22:00:58 jmc Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: December 19 2013 $
35.Dt STRNCAT 3
36.Os
37.Sh NAME
38.Nm strncat
39.Nd concatenate a string with part of another
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strncat "char *s" "const char *append" "size_t count"
44.Sh DESCRIPTION
45The
46.Fn strncat
47function appends not more than
48.Fa count
49characters of the NUL-terminated string
50.Fa append
51to the end of the NUL-terminated string
52.Fa s .
53Space for the terminating
54.Ql \e0
55should not be included in
56.Fa count .
57The string
58.Fa s
59must have sufficient space to hold the result.
60.Sh RETURN VALUES
61The
62.Fn strncat
63function returns the pointer
64.Fa s .
65.Sh EXAMPLES
66The following appends
67.Dq Li abc
68to
69.Va chararray :
70.Bd -literal -offset indent
71char *letters = "abcdefghi";
72
73(void)strncat(chararray, letters, 3);
74.Ed
75.Pp
76The following example shows how to use
77.Fn strncat
78safely in conjunction with
79.Xr strncpy 3 .
80.Bd -literal -offset indent
81char buf[BUFSIZ];
82char *input, *suffix;
83
84(void)strncpy(buf, input, sizeof(buf) - 1);
85buf[sizeof(buf) - 1] = '\e0';
86(void)strncat(buf, suffix, sizeof(buf) - 1 - strlen(buf));
87.Ed
88.Pp
89The above will copy as many characters from
90.Va input
91to
92.Va buf
93as will fit.
94It then appends as many characters from
95.Va suffix
96as will fit (or none
97if there is no space).
98For operations like this, the
99.Xr strlcpy 3
100and
101.Xr strlcat 3
102functions are a better choice, as shown below.
103.Bd -literal -offset indent
104(void)strlcpy(buf, input, sizeof(buf));
105(void)strlcat(buf, suffix, sizeof(buf));
106.Ed
107.Sh SEE ALSO
108.Xr bcopy 3 ,
109.Xr memccpy 3 ,
110.Xr memcpy 3 ,
111.Xr memmove 3 ,
112.Xr strcat 3 ,
113.Xr strcpy 3 ,
114.Xr strlcpy 3 ,
115.Xr wcscat 3 ,
116.Xr wcslcpy 3
117.Sh STANDARDS
118The
119.Fn strcat
120and
121.Fn strncat
122functions conform to
123.St -ansiC .
124.Sh HISTORY
125The
126.Fn strncat
127function first appeared in
128.At v7 .
diff --git a/src/lib/libc/string/strncat.c b/src/lib/libc/string/strncat.c
new file mode 100644
index 0000000000..c4df4f2fad
--- /dev/null
+++ b/src/lib/libc/string/strncat.c
@@ -0,0 +1,57 @@
1/* $OpenBSD: strncat.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Concatenate src on the end of dst. At most strlen(dst)+n+1 bytes
38 * are written at dst (at most n+1 bytes being appended). Return dst.
39 */
40char *
41strncat(char *dst, const char *src, size_t n)
42{
43 if (n != 0) {
44 char *d = dst;
45 const char *s = src;
46
47 while (*d != 0)
48 d++;
49 do {
50 if ((*d = *s++) == 0)
51 break;
52 d++;
53 } while (--n != 0);
54 *d = 0;
55 }
56 return (dst);
57}
diff --git a/src/lib/libc/string/strncmp.c b/src/lib/libc/string/strncmp.c
new file mode 100644
index 0000000000..0aea80d7d9
--- /dev/null
+++ b/src/lib/libc/string/strncmp.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strncmp.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
2
3/*
4 * Copyright (c) 1989 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#if !defined(_KERNEL) && !defined(_STANDALONE)
33#include <string.h>
34#else
35#include <lib/libkern/libkern.h>
36#endif
37
38int
39strncmp(const char *s1, const char *s2, size_t n)
40{
41
42 if (n == 0)
43 return (0);
44 do {
45 if (*s1 != *s2++)
46 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
47 if (*s1++ == 0)
48 break;
49 } while (--n != 0);
50 return (0);
51}
diff --git a/src/lib/libc/string/strncpy.3 b/src/lib/libc/string/strncpy.3
new file mode 100644
index 0000000000..dd8ddb86fc
--- /dev/null
+++ b/src/lib/libc/string/strncpy.3
@@ -0,0 +1,153 @@
1.\" $OpenBSD: strncpy.3,v 1.1 2013/12/19 20:52:37 millert Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: December 19 2013 $
35.Dt STRNCPY 3
36.Os
37.Sh NAME
38.Nm strncpy
39.Nd copy part of a string to another
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strncpy "char *dst" "const char *src" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn strncpy
47function copies not more than
48.Fa len
49characters from the string
50.Fa src
51to
52.Fa dst .
53If
54.Fa src
55is less than
56.Fa len
57characters long,
58it appends
59.Ql \e0
60characters for the rest of
61.Fa len .
62If the length of
63.Fa src
64is greater than or equal to
65.Fa len ,
66.Fa dst
67will
68.Em not
69be NUL-terminated.
70.Pp
71If the
72.Fa src
73and
74.Fa dst
75strings overlap, the behavior is undefined.
76.Sh RETURN VALUES
77The
78.Fn strncpy
79function returns
80.Fa dst .
81.Sh EXAMPLES
82The following sets
83.Va chararray
84to
85.Dq abc\e0\e0\e0 :
86.Bd -literal -offset indent
87(void)strncpy(chararray, "abc", 6);
88.Ed
89.Pp
90The following sets
91.Va chararray
92to
93.Dq abcdef
94and does
95.Em not
96NUL terminate
97.Va chararray
98because the length of the source string is greater than or equal to the
99length parameter.
100.Fn strncpy
101.Em only
102NUL terminates the destination string when the length of the source
103string is less than the length parameter.
104.Bd -literal -offset indent
105(void)strncpy(chararray, "abcdefgh", 6);
106.Ed
107.Pp
108The following copies as many characters from
109.Va input
110to
111.Va buf
112as will fit and NUL terminates the result.
113Because
114.Fn strncpy
115does
116.Em not
117guarantee to NUL terminate the string itself, it must be done by hand.
118.Bd -literal -offset indent
119char buf[BUFSIZ];
120
121(void)strncpy(buf, input, sizeof(buf) - 1);
122buf[sizeof(buf) - 1] = '\e0';
123.Ed
124.Pp
125Note that
126.Xr strlcpy 3
127is a better choice for this kind of operation.
128The equivalent using
129.Xr strlcpy 3
130is simply:
131.Bd -literal -offset indent
132(void)strlcpy(buf, input, sizeof(buf));
133.Ed
134.Sh SEE ALSO
135.Xr bcopy 3 ,
136.Xr memccpy 3 ,
137.Xr memcpy 3 ,
138.Xr memmove 3 ,
139.Xr strcat 3 ,
140.Xr strlcpy 3 ,
141.Xr strncat 3 ,
142.Xr wcscpy 3 ,
143.Xr wcslcpy 3
144.Sh STANDARDS
145The
146.Fn strncpy
147function conforms to
148.St -ansiC .
149.Sh HISTORY
150The
151.Fn strncpy
152function first appeared in
153.At v7 .
diff --git a/src/lib/libc/string/strncpy.c b/src/lib/libc/string/strncpy.c
new file mode 100644
index 0000000000..4426cbe2e3
--- /dev/null
+++ b/src/lib/libc/string/strncpy.c
@@ -0,0 +1,62 @@
1/* $OpenBSD: strncpy.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if !defined(_KERNEL) && !defined(_STANDALONE)
36#include <string.h>
37#else
38#include <lib/libkern/libkern.h>
39#endif
40
41/*
42 * Copy src to dst, truncating or null-padding to always copy n bytes.
43 * Return dst.
44 */
45char *
46strncpy(char *dst, const char *src, size_t n)
47{
48 if (n != 0) {
49 char *d = dst;
50 const char *s = src;
51
52 do {
53 if ((*d++ = *s++) == 0) {
54 /* NUL pad the remaining n-1 bytes */
55 while (--n != 0)
56 *d++ = 0;
57 break;
58 }
59 } while (--n != 0);
60 }
61 return (dst);
62}
diff --git a/src/lib/libc/string/strndup.c b/src/lib/libc/string/strndup.c
new file mode 100644
index 0000000000..27701ac555
--- /dev/null
+++ b/src/lib/libc/string/strndup.c
@@ -0,0 +1,39 @@
1/* $OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $ */
2
3/*
4 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
21#include <stddef.h>
22#include <stdlib.h>
23#include <string.h>
24
25char *
26strndup(const char *str, size_t maxlen)
27{
28 char *copy;
29 size_t len;
30
31 len = strnlen(str, maxlen);
32 copy = malloc(len + 1);
33 if (copy != NULL) {
34 (void)memcpy(copy, str, len);
35 copy[len] = '\0';
36 }
37
38 return copy;
39}
diff --git a/src/lib/libc/string/strnlen.c b/src/lib/libc/string/strnlen.c
new file mode 100644
index 0000000000..a5e13ae04e
--- /dev/null
+++ b/src/lib/libc/string/strnlen.c
@@ -0,0 +1,36 @@
1/* $OpenBSD: strnlen.c,v 1.4 2012/04/26 01:22:31 matthew Exp $ */
2
3/*
4 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
21#if !defined(_KERNEL) && !defined(_STANDALONE)
22#include <string.h>
23#else
24#include <lib/libkern/libkern.h>
25#endif
26
27size_t
28strnlen(const char *str, size_t maxlen)
29{
30 const char *cp;
31
32 for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
33 ;
34
35 return (size_t)(cp - str);
36}
diff --git a/src/lib/libc/string/strpbrk.3 b/src/lib/libc/string/strpbrk.3
new file mode 100644
index 0000000000..b758df6854
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.3
@@ -0,0 +1,80 @@
1.\" $OpenBSD: strpbrk.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRPBRK 3
36.Os
37.Sh NAME
38.Nm strpbrk
39.Nd locate multiple characters in string
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strpbrk "const char *s" "const char *charset"
44.Sh DESCRIPTION
45The
46.Fn strpbrk
47function locates in the NUL-terminated string
48.Fa s
49the first occurrence of any character in the string
50.Fa charset
51and returns a pointer to this character.
52If no characters from
53.Fa charset
54occur anywhere in
55.Fa s ,
56.Fn strpbrk
57returns
58.Dv NULL .
59.Sh SEE ALSO
60.Xr memchr 3 ,
61.Xr strchr 3 ,
62.Xr strcspn 3 ,
63.Xr strrchr 3 ,
64.Xr strsep 3 ,
65.Xr strspn 3 ,
66.Xr strstr 3 ,
67.Xr strtok 3 ,
68.Xr wcspbrk 3
69.Sh STANDARDS
70The
71.Fn strpbrk
72function conforms to
73.St -ansiC .
74.Sh HISTORY
75The
76.Fn strpbrk
77function first appeared in
78.At III
79and was reimplemented for
80.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strpbrk.c b/src/lib/libc/string/strpbrk.c
new file mode 100644
index 0000000000..cd3b71c0d3
--- /dev/null
+++ b/src/lib/libc/string/strpbrk.c
@@ -0,0 +1,48 @@
1/* $OpenBSD: strpbrk.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1985 Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <string.h>
32
33/*
34 * Find the first occurrence in s1 of a character in s2 (excluding NUL).
35 */
36char *
37strpbrk(const char *s1, const char *s2)
38{
39 const char *scanp;
40 int c, sc;
41
42 while ((c = *s1++) != 0) {
43 for (scanp = s2; (sc = *scanp++) != 0;)
44 if (sc == c)
45 return ((char *)(s1 - 1));
46 }
47 return (NULL);
48}
diff --git a/src/lib/libc/string/strrchr.3 b/src/lib/libc/string/strrchr.3
new file mode 100644
index 0000000000..046b28ce56
--- /dev/null
+++ b/src/lib/libc/string/strrchr.3
@@ -0,0 +1,116 @@
1.\" $OpenBSD: strrchr.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRRCHR 3
36.Os
37.Sh NAME
38.Nm strrchr ,
39.Nm rindex
40.Nd locate last occurrence of a character in a string
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn strrchr "const char *s" "int c"
45.Ft char *
46.Fn rindex "const char *s" "int c"
47.Sh DESCRIPTION
48The
49.Fn strrchr
50function locates the last occurrence of the character
51.Fa c
52in the string
53.Fa s .
54The terminating
55.Tn NUL
56character is considered part of the string.
57If
58.Fa c
59is
60.Ql \e0 ,
61.Fn strrchr
62locates the terminating
63.Ql \e0 .
64.Pp
65The
66.Fn rindex
67function is an old synonym for
68.Fn strrchr .
69.Sh RETURN VALUES
70The
71.Fn strrchr
72function returns a pointer to the located character or
73.Dv NULL
74if the character does not appear in the string.
75.Sh EXAMPLES
76After the following call to
77.Fn strrchr ,
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
87.Sh SEE ALSO
88.Xr memchr 3 ,
89.Xr strchr 3 ,
90.Xr strcspn 3 ,
91.Xr strpbrk 3 ,
92.Xr strsep 3 ,
93.Xr strspn 3 ,
94.Xr strstr 3 ,
95.Xr strtok 3 ,
96.Xr wcsrchr 3
97.Sh STANDARDS
98The
99.Fn strrchr
100function conforms to
101.St -ansiC .
102.Pp
103The
104.Fn rindex
105function is deprecated and shouldn't be used in new code.
106.Sh HISTORY
107The
108.Fn rindex
109function first appeared in
110.At v7 .
111The
112.Fn strrchr
113function first appeared in
114.At III
115and was reimplemented for
116.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strsep.3 b/src/lib/libc/string/strsep.3
new file mode 100644
index 0000000000..77053f66d7
--- /dev/null
+++ b/src/lib/libc/string/strsep.3
@@ -0,0 +1,110 @@
1.\" $OpenBSD: strsep.3,v 1.14 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" 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.\" @(#)strsep.3 8.1 (Berkeley) 6/9/93
34.\"
35.Dd $Mdocdate: June 5 2013 $
36.Dt STRSEP 3
37.Os
38.Sh NAME
39.Nm strsep
40.Nd separate strings
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn strsep "char **stringp" "const char *delim"
45.Sh DESCRIPTION
46The
47.Fn strsep
48function locates, in the string referenced by
49.Fa *stringp ,
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
60.Fa *stringp .
61The original value of
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
71to
72.Ql \e0 .
73.Pp
74If
75.Fa *stringp
76is initially
77.Dv NULL ,
78.Fn strsep
79returns
80.Dv NULL .
81.Sh EXAMPLES
82The following uses
83.Fn strsep
84to parse a string, containing tokens delimited by whitespace, into an
85argument vector:
86.Bd -literal -offset indent
87char **ap, *argv[10], *inputstring;
88
89for (ap = argv; ap < &argv[9] &&
90 (*ap = strsep(&inputstring, " \et")) != NULL;) {
91 if (**ap != '\e0')
92 ap++;
93}
94*ap = NULL;
95.Ed
96.Sh HISTORY
97The
98.Fn strsep
99function first appeared in
100.Bx 4.3 Reno .
101It is intended as a replacement for the
102.Xr strtok 3
103function.
104While the
105.Xr strtok 3
106function should be preferred for portability reasons (it conforms to
107.St -ansiC )
108it is unable to handle empty fields, i.e., detect fields delimited by
109two adjacent delimiter characters, or to be used for more than a single
110string at a time.
diff --git a/src/lib/libc/string/strsep.c b/src/lib/libc/string/strsep.c
new file mode 100644
index 0000000000..2ffc4b4c46
--- /dev/null
+++ b/src/lib/libc/string/strsep.c
@@ -0,0 +1,70 @@
1/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp 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 <string.h>
33
34/*
35 * Get next token from string *stringp, where tokens are possibly-empty
36 * strings separated by characters from delim.
37 *
38 * Writes NULs into the string at *stringp to end tokens.
39 * delim need not remain constant from call to call.
40 * On return, *stringp points past the last NUL written (if there might
41 * be further tokens), or is NULL (if there are definitely no more tokens).
42 *
43 * If *stringp is NULL, strsep returns NULL.
44 */
45char *
46strsep(char **stringp, const char *delim)
47{
48 char *s;
49 const char *spanp;
50 int c, sc;
51 char *tok;
52
53 if ((s = *stringp) == NULL)
54 return (NULL);
55 for (tok = s;;) {
56 c = *s++;
57 spanp = delim;
58 do {
59 if ((sc = *spanp++) == c) {
60 if (c == 0)
61 s = NULL;
62 else
63 s[-1] = 0;
64 *stringp = s;
65 return (tok);
66 }
67 } while (sc != 0);
68 }
69 /* NOTREACHED */
70}
diff --git a/src/lib/libc/string/strsignal.3 b/src/lib/libc/string/strsignal.3
new file mode 100644
index 0000000000..3261f699d8
--- /dev/null
+++ b/src/lib/libc/string/strsignal.3
@@ -0,0 +1,68 @@
1.\" Copyright (c) 1980, 1991 Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" the American National Standards Committee X3, on Information
6.\" Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strsignal.3,v 1.8 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRSIGNAL 3
36.Os
37.Sh NAME
38.Nm strsignal
39.Nd get signal description string
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strsignal "int sig"
44.Sh DESCRIPTION
45The
46.Fn strsignal
47function returns a pointer to the language-dependent string describing
48a signal.
49.Pp
50The array pointed to is not to be modified by the program, but may be
51overwritten by subsequent calls to
52.Fn strsignal .
53.Sh SEE ALSO
54.Xr intro 2 ,
55.Xr psignal 3 ,
56.Xr setlocale 3
57.Sh STANDARDS
58The
59.Fn strsignal
60function conforms to
61.St -p1003.1-2008 .
62.Sh HISTORY
63The
64.Fn strsignal
65function first appeared in
66.At V.4
67and was reimplemented for
68.Nx 1.0 .
diff --git a/src/lib/libc/string/strsignal.c b/src/lib/libc/string/strsignal.c
new file mode 100644
index 0000000000..aa541cefed
--- /dev/null
+++ b/src/lib/libc/string/strsignal.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <string.h>
31#include <limits.h>
32
33extern char *__strsignal(int, char *);
34
35char *
36strsignal(int sig)
37{
38 static char buf[NL_TEXTMAX];
39
40 return __strsignal(sig, buf);
41}
diff --git a/src/lib/libc/string/strspn.3 b/src/lib/libc/string/strspn.3
new file mode 100644
index 0000000000..e339d9b6af
--- /dev/null
+++ b/src/lib/libc/string/strspn.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: strspn.3,v 1.11 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRSPN 3
36.Os
37.Sh NAME
38.Nm strspn
39.Nd span a string
40.Sh SYNOPSIS
41.In string.h
42.Ft size_t
43.Fn strspn "const char *s" "const char *charset"
44.Sh DESCRIPTION
45The
46.Fn strspn
47function spans the initial part of the NUL-terminated string
48.Fa s
49as long as the characters from
50.Fa s
51occur in string
52.Fa charset .
53.Sh RETURN VALUES
54The
55.Fn strspn
56function returns 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
71.Sh SEE ALSO
72.Xr memchr 3 ,
73.Xr strchr 3 ,
74.Xr strcspn 3 ,
75.Xr strpbrk 3 ,
76.Xr strrchr 3 ,
77.Xr strsep 3 ,
78.Xr strstr 3 ,
79.Xr strtok 3 ,
80.Xr wcsspn 3
81.Sh STANDARDS
82The
83.Fn strspn
84function conforms to
85.St -ansiC .
86.Sh HISTORY
87The
88.Fn strspn
89function first appeared in
90.At III
91and was reimplemented for
92.Bx 4.3 Tahoe .
diff --git a/src/lib/libc/string/strspn.c b/src/lib/libc/string/strspn.c
new file mode 100644
index 0000000000..385649c041
--- /dev/null
+++ b/src/lib/libc/string/strspn.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*
3 * Copyright (c) 1989 The Regents of the University of California.
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. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <string.h>
32
33/*
34 * Span the string s2 (skip characters that are in s2).
35 */
36size_t
37strspn(const char *s1, const char *s2)
38{
39 const char *p = s1, *spanp;
40 char c, sc;
41
42 /*
43 * Skip any characters in s2, excluding the terminating \0.
44 */
45cont:
46 c = *p++;
47 for (spanp = s2; (sc = *spanp++) != 0;)
48 if (sc == c)
49 goto cont;
50 return (p - 1 - s1);
51}
diff --git a/src/lib/libc/string/strstr.3 b/src/lib/libc/string/strstr.3
new file mode 100644
index 0000000000..1f79d45590
--- /dev/null
+++ b/src/lib/libc/string/strstr.3
@@ -0,0 +1,100 @@
1.\" $OpenBSD: strstr.3,v 1.12 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRSTR 3
36.Os
37.Sh NAME
38.Nm strstr , strcasestr
39.Nd locate a substring in a string
40.Sh SYNOPSIS
41.In string.h
42.Ft char *
43.Fn strstr "const char *big" "const char *little"
44.Ft char *
45.Fn strcasestr "const char *big" "const char *little"
46.Sh DESCRIPTION
47The
48.Fn strstr
49function locates the first occurrence of the NUL-terminated string
50.Fa little
51in the NUL-terminated string
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
60If
61.Fa little
62is an empty string,
63.Fa big
64is returned;
65if
66.Fa little
67occurs nowhere in
68.Fa big ,
69.Dv NULL
70is returned;
71otherwise a pointer to the first character of the first occurrence of
72.Fa little
73is returned.
74.Sh SEE ALSO
75.Xr memchr 3 ,
76.Xr strchr 3 ,
77.Xr strcspn 3 ,
78.Xr strpbrk 3 ,
79.Xr strrchr 3 ,
80.Xr strsep 3 ,
81.Xr strspn 3 ,
82.Xr strtok 3 ,
83.Xr wcsstr 3
84.Sh STANDARDS
85The
86.Fn strstr
87function conforms to
88.St -ansiC .
89.Sh HISTORY
90The
91.Fn strstr
92function first appeared in
93.Bx 4.3 Reno .
94The
95.Fn strcasestr
96function appeared in glibc 2.1,
97was reimplemented for
98.Fx 4.5
99and ported to
100.Ox 3.8 .
diff --git a/src/lib/libc/string/strstr.c b/src/lib/libc/string/strstr.c
new file mode 100644
index 0000000000..95a865bf79
--- /dev/null
+++ b/src/lib/libc/string/strstr.c
@@ -0,0 +1,56 @@
1/* $OpenBSD: strstr.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Find the first occurrence of find in s.
38 */
39char *
40strstr(const char *s, const char *find)
41{
42 char c, sc;
43 size_t len;
44
45 if ((c = *find++) != 0) {
46 len = strlen(find);
47 do {
48 do {
49 if ((sc = *s++) == 0)
50 return (NULL);
51 } while (sc != c);
52 } while (strncmp(s, find, len) != 0);
53 s--;
54 }
55 return ((char *)s);
56}
diff --git a/src/lib/libc/string/strtok.3 b/src/lib/libc/string/strtok.3
new file mode 100644
index 0000000000..046a43b6b1
--- /dev/null
+++ b/src/lib/libc/string/strtok.3
@@ -0,0 +1,166 @@
1.\" $OpenBSD: strtok.3,v 1.21 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1988, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" the American National Standards Committee X3, on Information
8.\" Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRTOK 3
36.Os
37.Sh NAME
38.Nm strtok ,
39.Nm strtok_r
40.Nd string token operations
41.Sh SYNOPSIS
42.In string.h
43.Ft char *
44.Fn strtok "char *str" "const char *sep"
45.Ft char *
46.Fn strtok_r "char *str" "const char *sep" "char **last"
47.Sh DESCRIPTION
48.Bf -symbolic
49This interface is obsoleted by
50.Xr strsep 3 .
51.Ef
52.Pp
53The
54.Fn strtok
55function is used to isolate sequential tokens in a NUL-terminated string,
56.Fa str .
57These tokens are separated in the string by at least one of the
58characters in
59.Fa sep .
60The first time that
61.Fn strtok
62is called,
63.Fa str
64should be specified; subsequent calls, wishing to obtain further tokens
65from the same string, should pass a null pointer instead.
66The separator string,
67.Fa sep ,
68must be supplied each time, and may change between calls.
69.Pp
70The
71.Fn strtok_r
72function is a version of
73.Fn strtok
74that takes an explicit context argument and is reentrant.
75.Pp
76Since
77.Fn strtok
78and
79.Fn strtok_r
80modify the string,
81.Fa str
82should not point to an area in the initialized data segment.
83.Sh RETURN VALUES
84The
85.Fn strtok
86and
87.Fn strtok_r
88functions return a pointer to the beginning of each subsequent token
89in the string, after replacing the separator character itself with an
90.Tn ASCII NUL
91character.
92When no more tokens remain, a null pointer is returned.
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 .
128.Sh SEE ALSO
129.Xr memchr 3 ,
130.Xr strchr 3 ,
131.Xr strcspn 3 ,
132.Xr strpbrk 3 ,
133.Xr strrchr 3 ,
134.Xr strsep 3 ,
135.Xr strspn 3 ,
136.Xr strstr 3 ,
137.Xr wcstok 3
138.Sh STANDARDS
139The
140.Fn strtok
141function conforms to
142.St -ansiC .
143.Sh HISTORY
144The
145.Fn strtok
146function first appeared in
147.At III
148and was reimplemented for
149.Bx 4.3 Tahoe .
150The
151.Fn strtok_r
152function first appeared in
153.Nx 1.3
154and was reimplemented for
155.Ox 2.7 .
156.Sh BUGS
157The System V
158.Fn strtok ,
159if handed a string containing only delimiter characters,
160will not alter the next starting point, so that a call to
161.Fn strtok
162with a different (or empty) delimiter string
163may return a non-null value.
164Since this implementation always alters the next starting point,
165such a sequence of calls would always return
166.Dv NULL .
diff --git a/src/lib/libc/string/strtok.c b/src/lib/libc/string/strtok.c
new file mode 100644
index 0000000000..4e963a019e
--- /dev/null
+++ b/src/lib/libc/string/strtok.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <string.h>
31
32char *
33strtok(char *s, const char *delim)
34{
35 static char *last;
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
47
48 if (s == NULL && (s = *last) == NULL)
49 return (NULL);
50
51 /*
52 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
53 */
54cont:
55 c = *s++;
56 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
57 if (c == sc)
58 goto cont;
59 }
60
61 if (c == 0) { /* no non-delimiter characters */
62 *last = NULL;
63 return (NULL);
64 }
65 tok = s - 1;
66
67 /*
68 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
69 * Note that delim must have one NUL; we stop if we see that, too.
70 */
71 for (;;) {
72 c = *s++;
73 spanp = (char *)delim;
74 do {
75 if ((sc = *spanp++) == c) {
76 if (c == 0)
77 s = NULL;
78 else
79 s[-1] = 0;
80 *last = s;
81 return (tok);
82 }
83 } while (sc != 0);
84 }
85 /* NOTREACHED */
86}
diff --git a/src/lib/libc/string/strxfrm.3 b/src/lib/libc/string/strxfrm.3
new file mode 100644
index 0000000000..481f741cb7
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.3
@@ -0,0 +1,79 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" This code is derived from software contributed to Berkeley by
5.\" Chris Torek and the American National Standards Committee X3,
6.\" on Information Processing Systems.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" $OpenBSD: strxfrm.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt STRXFRM 3
36.Os
37.Sh NAME
38.Nm strxfrm
39.Nd transform a string under locale
40.Sh SYNOPSIS
41.In string.h
42.Ft size_t
43.Fn strxfrm "char *dst" "const char *src" "size_t n"
44.Sh DESCRIPTION
45The idea of
46.Fn strxfrm
47is to
48.Dq un-localize
49a string: the function transforms
50.Ar src ,
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.
58.Sh SEE ALSO
59.Xr bcmp 3 ,
60.Xr memcmp 3 ,
61.Xr setlocale 3 ,
62.Xr strcasecmp 3 ,
63.Xr strcmp 3 ,
64.Xr strcoll 3
65.Sh STANDARDS
66The
67.Fn strxfrm
68function conforms to
69.St -ansiC .
70.Sh HISTORY
71The
72.Fn strxfrm
73function first appeared in
74.Bx 4.3 Reno .
75.Sh BUGS
76Since locales are not fully implemented on
77.Ox ,
78.Fn strxfrm
79just returns a copy of the original string.
diff --git a/src/lib/libc/string/strxfrm.c b/src/lib/libc/string/strxfrm.c
new file mode 100644
index 0000000000..6f289c901e
--- /dev/null
+++ b/src/lib/libc/string/strxfrm.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: strxfrm.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2/*-
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Chris Torek.
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 <string.h>
35
36/*
37 * Transform src, storing the result in dst, such that
38 * strcmp() on transformed strings returns what strcoll()
39 * on the original untransformed strings would return.
40 */
41size_t
42strxfrm(char *dst, const char *src, size_t n)
43{
44
45 /*
46 * Since locales are unimplemented, this is just a copy.
47 */
48 if (n == 0)
49 return (strlen(src));
50 return (strlcpy(dst, src, n));
51}
diff --git a/src/lib/libc/string/swab.3 b/src/lib/libc/string/swab.3
new file mode 100644
index 0000000000..77e5a9ccbc
--- /dev/null
+++ b/src/lib/libc/string/swab.3
@@ -0,0 +1,61 @@
1.\" Copyright (c) 1990, 1991 The Regents of the University of California.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\" 3. Neither the name of the University nor the names of its contributors
13.\" may be used to endorse or promote products derived from this software
14.\" without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\" $OpenBSD: swab.3,v 1.8 2013/06/05 03:39:23 tedu Exp $
29.\"
30.Dd $Mdocdate: June 5 2013 $
31.Dt SWAB 3
32.Os
33.Sh NAME
34.Nm swab
35.Nd swap adjacent bytes
36.Sh SYNOPSIS
37.In unistd.h
38.Ft void
39.Fn swab "const void *src" "void *dst" "size_t len"
40.Sh DESCRIPTION
41The function
42.Fn swab
43copies
44.Fa len
45bytes from the location referenced by
46.Fa src
47to the location referenced by
48.Fa dst ,
49swapping adjacent bytes.
50.Pp
51The argument
52.Fa len
53must be an even number.
54.Sh SEE ALSO
55.Xr bzero 3 ,
56.Xr memset 3
57.Sh HISTORY
58The
59.Fn swab
60function first appeared in
61.At v7 .
diff --git a/src/lib/libc/string/swab.c b/src/lib/libc/string/swab.c
new file mode 100644
index 0000000000..b74db7e62a
--- /dev/null
+++ b/src/lib/libc/string/swab.c
@@ -0,0 +1,61 @@
1/* $OpenBSD: swab.c,v 1.8 2008/03/15 21:54:09 ray Exp $ */
2/*
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Jeffrey Mogul.
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 <unistd.h>
35
36void
37swab(const void *from, void *to, size_t len)
38{
39 size_t n;
40 char *fp, *tp;
41 char temp;
42
43 n = (len / 2) + 1;
44 fp = (char *)from;
45 tp = (char *)to;
46#define STEP do { \
47 temp = *fp++; \
48 *tp++ = *fp++; \
49 *tp++ = temp; \
50} while (0)
51 /* round to multiple of 8 */
52 while ((--n) & 07)
53 STEP;
54 n >>= 3;
55 if (n == 0)
56 return;
57 while (n-- != 0) {
58 STEP; STEP; STEP; STEP;
59 STEP; STEP; STEP; STEP;
60 }
61}
diff --git a/src/lib/libc/string/timingsafe_bcmp.c b/src/lib/libc/string/timingsafe_bcmp.c
new file mode 100644
index 0000000000..9c4287cf63
--- /dev/null
+++ b/src/lib/libc/string/timingsafe_bcmp.c
@@ -0,0 +1,33 @@
1/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */
2/*
3 * Copyright (c) 2010 Damien Miller. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#if !defined(_KERNEL) && !defined(_STANDALONE)
19#include <string.h>
20#else
21#include <lib/libkern/libkern.h>
22#endif
23
24int
25timingsafe_bcmp(const void *b1, const void *b2, size_t n)
26{
27 const unsigned char *p1 = b1, *p2 = b2;
28 int ret = 0;
29
30 for (; n > 0; n--)
31 ret |= *p1++ ^ *p2++;
32 return (ret != 0);
33}
diff --git a/src/lib/libc/string/wcscasecmp.3 b/src/lib/libc/string/wcscasecmp.3
new file mode 100644
index 0000000000..daf397aece
--- /dev/null
+++ b/src/lib/libc/string/wcscasecmp.3
@@ -0,0 +1,94 @@
1.\" $OpenBSD: wcscasecmp.3,v 1.4 2013/07/16 15:21:11 schwarze Exp $
2.\"
3.\" Copyright (c) 1990, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek.
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\" @(#)strcasecmp.3 8.1 (Berkeley) 6/9/93
33.\"
34.Dd $Mdocdate: July 16 2013 $
35.Dt WCSCASECMP 3
36.Os
37.Sh NAME
38.Nm wcscasecmp ,
39.Nm wcsncasecmp
40.Nd compare wide strings, ignoring case
41.Sh SYNOPSIS
42.In wchar.h
43.Ft int
44.Fn wcscasecmp "const wchar_t *s1" "const wchar_t *s2"
45.Ft int
46.Fn wcsncasecmp "const wchar_t *s1" "const wchar_t *s2" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn wcscasecmp
50and
51.Fn wcsncasecmp
52functions compare the wide strings
53.Fa s1
54and
55.Fa s2
56and return an integer greater than, equal to, or less than 0,
57according to whether
58.Fa s1
59is lexicographically greater than, equal to, or less than
60.Fa s2
61after translation of each corresponding wide character to lower case.
62The wide strings themselves are not modified.
63.Pp
64.Fn wcsncasecmp
65compares at most
66.Fa len
67wide characters.
68.Sh SEE ALSO
69.Xr strcasecmp 3 ,
70.Xr wcscmp 3 ,
71.Xr wmemcmp 3
72.Sh STANDARDS
73The
74.Fn wcscasecmp
75and
76.Fn wcsncasecmp
77functions conform to
78.St -p1003.1-2008 .
79.Sh HISTORY
80The
81.Fn wcscasecmp
82and
83.Fn wcsncasecmp
84functions first appeared in
85.Ox 5.0 .
86.Sh AUTHORS
87The
88.Ox
89versions of
90.Fn wcscasecmp
91and
92.Fn wcsncasecmp
93were implemented by
94.An Marc Espie Aq Mt espie@openbsd.org .
diff --git a/src/lib/libc/string/wcscasecmp.c b/src/lib/libc/string/wcscasecmp.c
new file mode 100644
index 0000000000..b14997ee75
--- /dev/null
+++ b/src/lib/libc/string/wcscasecmp.c
@@ -0,0 +1,61 @@
1/* $OpenBSD: wcscasecmp.c,v 1.2 2011/06/01 19:29:48 naddy Exp $ */
2
3/*
4 * Copyright (c) 2011 Marc Espie
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
19 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <wchar.h>
29#include <wctype.h>
30#include "locale/runetype.h"
31
32int
33wcscasecmp(const wchar_t *s1, const wchar_t *s2)
34{
35 wchar_t l1, l2;
36
37 while ((l1 = towlower(*s1++)) == (l2 = towlower(*s2++))) {
38 if (l1 == 0)
39 return (0);
40 }
41 /* XXX assumes wchar_t = int */
42 return ((rune_t)l1 - (rune_t)l2);
43}
44
45int
46wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
47{
48 wchar_t l1, l2;
49
50 if (n == 0)
51 return (0);
52 do {
53 if (((l1 = towlower(*s1++))) != (l2 = towlower(*s2++))) {
54 /* XXX assumes wchar_t = int */
55 return ((rune_t)l1 - (rune_t)l2);
56 }
57 if (l1 == 0)
58 break;
59 } while (--n != 0);
60 return (0);
61}
diff --git a/src/lib/libc/string/wcscat.3 b/src/lib/libc/string/wcscat.3
new file mode 100644
index 0000000000..9b7588cf9e
--- /dev/null
+++ b/src/lib/libc/string/wcscat.3
@@ -0,0 +1,115 @@
1.\" $OpenBSD: wcscat.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSCAT 3
36.Os
37.Sh NAME
38.Nm wcscat ,
39.Nm wcsncat
40.Nd concatenate wide strings
41.Sh SYNOPSIS
42.In wchar.h
43.Ft wchar_t *
44.Fn wcscat "wchar_t * restrict s" "const wchar_t * restrict append"
45.Ft wchar_t *
46.Fo wcsncat
47.Fa "wchar_t * restrict s"
48.Fa "const wchar_t * restrict append"
49.Fa "size_t count"
50.Fc
51.Sh DESCRIPTION
52The
53.Fn wcscat
54and
55.Fn wcsncat
56functions append a copy of the wide string
57.Fa append
58to the end of the wide string
59.Fa s ,
60then add a terminating null wide character (L'\e0').
61The wide string
62.Fa s
63must have sufficient space to hold the result.
64.Pp
65The
66.Fn wcsncat
67function appends not more than
68.Fa count
69wide characters where space for the terminating null wide character
70should not be included in
71.Fa count .
72.Sh RETURN VALUES
73The
74.Fn wcscat
75and
76.Fn wcsncat
77functions return the pointer
78.Fa s .
79.Sh SEE ALSO
80.Xr strcat 3 ,
81.Xr strlcpy 3 ,
82.Xr wcscpy 3 ,
83.Xr wcslcpy 3 ,
84.Xr wmemcpy 3 ,
85.Xr wmemmove 3
86.Sh STANDARDS
87The
88.Fn wcscat
89and
90.Fn wcsncat
91functions conform to
92.St -isoC-99
93and were first introduced in
94.St -isoC-amd1 .
95.Sh HISTORY
96The
97.Fn wcscat
98and
99.Fn wcsncat
100functions were ported from
101.Nx
102and first appeared in
103.Ox 3.8 .
104.Sh CAVEATS
105Using the functions
106.Fn wcscat
107and
108.Fn wcsncat
109is very error-prone with respect to buffer overflows;
110see the EXAMPLES section in
111.Xr strcat 3
112for correct usage.
113Using
114.Xr wcslcat 3
115is a better choice in most cases.
diff --git a/src/lib/libc/string/wcscat.c b/src/lib/libc/string/wcscat.c
new file mode 100644
index 0000000000..a4841a975a
--- /dev/null
+++ b/src/lib/libc/string/wcscat.c
@@ -0,0 +1,55 @@
1/* $OpenBSD: wcscat.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcscat.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcscat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
30 */
31
32#include <wchar.h>
33
34#if defined(APIWARN)
35__warn_references(wcscat,
36 "warning: wcscat() is almost always misused, please use wcslcat()");
37#endif
38
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.3 b/src/lib/libc/string/wcschr.3
new file mode 100644
index 0000000000..bb714b2099
--- /dev/null
+++ b/src/lib/libc/string/wcschr.3
@@ -0,0 +1,85 @@
1.\" $OpenBSD: wcschr.3,v 1.4 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSCHR 3
36.Os
37.Sh NAME
38.Nm wcschr
39.Nd locate first occurrence of a wide character in a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wcschr "const wchar_t *s" "wchar_t c"
44.Sh DESCRIPTION
45The
46.Fn wcschr
47function locates the first occurrence of the wide character
48.Fa c
49in the wide string
50.Fa s .
51The terminating null wide character is considered part of the wide string.
52If
53.Fa c
54is the null wide character (L'\e0'),
55.Fn wcschr
56locates the terminating null wide character.
57.Sh RETURN VALUES
58The
59.Fn wcschr
60function returns a pointer to the located wide character or
61.Dv NULL
62if the wide character does not appear in the wide string.
63.Sh SEE ALSO
64.Xr strchr 3 ,
65.Xr wcscspn 3 ,
66.Xr wcspbrk 3 ,
67.Xr wcsrchr 3 ,
68.Xr wcsspn 3 ,
69.Xr wcsstr 3 ,
70.Xr wcstok 3 ,
71.Xr wmemchr 3
72.Sh STANDARDS
73The
74.Fn wcschr
75function conforms to
76.St -isoC-99
77and was first introduced in
78.St -isoC-amd1 .
79.Sh HISTORY
80The
81.Fn wcschr
82function was ported from
83.Nx
84and first appeared in
85.Ox 3.8 .
diff --git a/src/lib/libc/string/wcschr.c b/src/lib/libc/string/wcschr.c
new file mode 100644
index 0000000000..b84a2d32e3
--- /dev/null
+++ b/src/lib/libc/string/wcschr.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: wcschr.c,v 1.4 2008/08/23 05:34:36 djm Exp $ */
2/* $NetBSD: wcschr.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcschr.c,v 1.2 2000/12/21 05:07:25 itojun Exp
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wcscmp.3
new file mode 100644
index 0000000000..53cd15a1f0
--- /dev/null
+++ b/src/lib/libc/string/wcscmp.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: wcscmp.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSCMP 3
36.Os
37.Sh NAME
38.Nm wcscmp ,
39.Nm wcsncmp
40.Nd compare wide strings
41.Sh SYNOPSIS
42.In wchar.h
43.Ft int
44.Fn wcscmp "const wchar_t *s1" "const wchar_t *s2"
45.Ft int
46.Fn wcsncmp "const wchar_t *s1" "const wchar_t *s2" "size_t len"
47.Sh DESCRIPTION
48The
49.Fn wcscmp
50and
51.Fn wcsncmp
52functions lexicographically compare the wide strings
53.Fa s1
54and
55.Fa s2 .
56The
57.Fn wcsncmp
58function compares at most
59.Fa len
60wide characters.
61.Sh RETURN VALUES
62The
63.Fn wcscmp
64and
65.Fn wcsncmp
66functions return an integer greater than, equal to, or less than 0, according
67to whether the wide string
68.Fa s1
69is greater than, equal to, or less than the wide string
70.Fa s2 .
71.Sh SEE ALSO
72.Xr strcmp 3 ,
73.Xr wcscasecmp 3 ,
74.Xr wmemcmp 3
75.Sh STANDARDS
76The
77.Fn wcscmp
78and
79.Fn wcsncmp
80functions conform to
81.St -isoC-99
82and were first introduced in
83.St -isoC-amd1 .
84.Sh HISTORY
85The
86.Fn wcscmp
87and
88.Fn wcsncmp
89functions were ported from
90.Nx
91and first appeared in
92.Ox 3.8 .
diff --git a/src/lib/libc/string/wcscmp.c b/src/lib/libc/string/wcscmp.c
new file mode 100644
index 0000000000..4a8f6ba3fb
--- /dev/null
+++ b/src/lib/libc/string/wcscmp.c
@@ -0,0 +1,51 @@
1/* $OpenBSD: wcscmp.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcscmp.c,v 1.5 2003/08/07 16:43:54 agc Exp $ */
3
4/*-
5 * Copyright (c) 1990, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Chris Torek.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <wchar.h>
37#include "locale/runetype.h"
38
39/*
40 * Compare strings.
41 */
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.3 b/src/lib/libc/string/wcscpy.3
new file mode 100644
index 0000000000..2277eb419a
--- /dev/null
+++ b/src/lib/libc/string/wcscpy.3
@@ -0,0 +1,129 @@
1.\" $OpenBSD: wcscpy.3,v 1.4 2013/09/25 21:49:31 millert Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: September 25 2013 $
35.Dt WCSCPY 3
36.Os
37.Sh NAME
38.Nm wcscpy ,
39.Nm wcsncpy
40.Nd copy wide strings
41.Sh SYNOPSIS
42.In wchar.h
43.Ft wchar_t *
44.Fn wcscpy "wchar_t * restrict dst" "const wchar_t * restrict src"
45.Ft wchar_t *
46.Fo wcsncpy
47.Fa "wchar_t * restrict dst"
48.Fa "const wchar_t * restrict src"
49.Fa "size_t len"
50.Fc
51.Sh DESCRIPTION
52The
53.Fn wcscpy
54and
55.Fn wcsncpy
56functions copy the wide string
57.Fa src
58to
59.Fa dst
60(including the terminating null wide character).
61.Pp
62The
63.Fn wcsncpy
64function copies not more than
65.Fa len
66wide characters to
67.Fa dst ,
68appending null wide characters if the length of
69.Fa src
70is less than
71.Fa len ,
72and
73.Em not
74terminating
75.Fa dst
76if the length of
77.Fa src
78is greater than or equal to
79.Fa len .
80.Pp
81If the
82.Fa src
83and
84.Fa dst
85strings overlap, the behavior is undefined.
86.Sh RETURN VALUES
87The
88.Fn wcscpy
89and
90.Fn wcsncpy
91functions return
92.Fa dst .
93.Sh SEE ALSO
94.Xr strcpy 3 ,
95.Xr strlcpy 3 ,
96.Xr wcscat 3 ,
97.Xr wcslcpy 3 ,
98.Xr wmemcpy 3 ,
99.Xr wmemmove 3
100.Sh STANDARDS
101The
102.Fn wcscpy
103and
104.Fn wcsncpy
105functions conform to
106.St -isoC-99
107and were first introduced in
108.St -isoC-amd1 .
109.Sh HISTORY
110The
111.Fn wcscpy
112and
113.Fn wcsncpy
114functions were ported from
115.Nx
116and first appeared in
117.Ox 3.8 .
118.Sh CAVEATS
119Using the functions
120.Fn wcscpy
121and
122.Fn wcsncpy
123is very error-prone with respect to buffer overflows;
124see the EXAMPLES section in
125.Xr strcpy 3
126for correct usage.
127Using
128.Xr wcslcpy 3
129is a better choice in most cases.
diff --git a/src/lib/libc/string/wcscpy.c b/src/lib/libc/string/wcscpy.c
new file mode 100644
index 0000000000..75fdb75fe4
--- /dev/null
+++ b/src/lib/libc/string/wcscpy.c
@@ -0,0 +1,52 @@
1/* $OpenBSD: wcscpy.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcscpy.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcscpy.c,v 1.2 2000/12/21 04:51:09 itojun Exp
30 */
31
32#include <wchar.h>
33
34#if defined(APIWARN)
35__warn_references(wcscpy,
36 "warning: wcscpy() is almost always misused, please use wcslcpy()");
37#endif
38
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.3 b/src/lib/libc/string/wcscspn.3
new file mode 100644
index 0000000000..520a739202
--- /dev/null
+++ b/src/lib/libc/string/wcscspn.3
@@ -0,0 +1,83 @@
1.\" $OpenBSD: wcscspn.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSCSPN 3
36.Os
37.Sh NAME
38.Nm wcscspn
39.Nd span the complement of a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft size_t
43.Fn wcscspn "const wchar_t *s" "const wchar_t *charset"
44.Sh DESCRIPTION
45The
46.Fn wcscspn
47function spans the initial part of the wide string
48.Fa s
49as long as the wide characters from
50.Fa s
51do not occur in string
52.Fa charset
53(it spans the
54.Em complement
55of
56.Fa charset ) .
57.Sh RETURN VALUES
58The
59.Fn wcscspn
60function returns the number of wide characters spanned.
61.Sh SEE ALSO
62.Xr strcspn 3 ,
63.Xr wcschr 3 ,
64.Xr wcspbrk 3 ,
65.Xr wcsrchr 3 ,
66.Xr wcsspn 3 ,
67.Xr wcsstr 3 ,
68.Xr wcstok 3 ,
69.Xr wmemchr 3
70.Sh STANDARDS
71The
72.Fn wcscspn
73function conforms to
74.St -isoC-99
75and was first introduced in
76.St -isoC-amd1 .
77.Sh HISTORY
78The
79.Fn wcscspn
80function was ported from
81.Nx
82and first appeared in
83.Ox 3.8 .
diff --git a/src/lib/libc/string/wcscspn.c b/src/lib/libc/string/wcscspn.c
new file mode 100644
index 0000000000..cf40092465
--- /dev/null
+++ b/src/lib/libc/string/wcscspn.c
@@ -0,0 +1,53 @@
1/* $OpenBSD: wcscspn.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcscspn.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcscspn.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
30 */
31
32#include <wchar.h>
33
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/wcsdup.3 b/src/lib/libc/string/wcsdup.3
new file mode 100644
index 0000000000..588a2571db
--- /dev/null
+++ b/src/lib/libc/string/wcsdup.3
@@ -0,0 +1,97 @@
1.\" $OpenBSD: wcsdup.3,v 1.4 2011/07/25 00:38:53 schwarze Exp $
2.\" $NetBSD: wcsdup.3,v 1.3 2010/12/16 17:42:28 wiz Exp $
3.\"
4.\" Copyright (c) 1990, 1991, 1993
5.\" The Regents of the University of California. All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\" notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\" 3. Neither the name of the University nor the names of its contributors
16.\" may be used to endorse or promote products derived from this software
17.\" without specific prior written permission.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29.\" SUCH DAMAGE.
30.\"
31.\" @(#)strdup.3 8.1 (Berkeley) 6/9/93
32.\"
33.Dd $Mdocdate: July 25 2011 $
34.Dt WCSDUP 3
35.Os
36.Sh NAME
37.Nm wcsdup
38.Nd save a copy of a wide string
39.Sh SYNOPSIS
40.In wchar.h
41.Ft wchar_t *
42.Fn wcsdup "const wchar_t *str"
43.Sh DESCRIPTION
44The
45.Fn wcsdup
46function
47allocates sufficient memory for a copy
48of the wide-character string
49.Fa str ,
50does the copy, and returns a pointer to it.
51The pointer may subsequently be used as an
52argument to the function
53.Xr free 3 .
54.Pp
55If insufficient memory is available,
56.Dv NULL
57is returned.
58.Sh EXAMPLES
59The following will point
60.Va p
61to an allocated area of memory containing the nul-terminated string
62.Qq foobar :
63.Bd -literal -offset indent
64const char *o = "foobar";
65wchar_t *p, b[32];
66size_t blen;
67
68blen = sizeof(b) / sizeof(b[0]);
69if (mbstowcs(b, o, blen) == (size_t)-1)
70 err(1, NULL);
71b[blen - 1] = 0;
72if ((p = wcsdup(b)) == NULL)
73 err(1, NULL);
74.Ed
75.Sh ERRORS
76The
77.Fn wcsdup
78function may fail and set the external variable
79.Va errno
80for any of the errors specified for the library function
81.Xr malloc 3 .
82.Sh SEE ALSO
83.Xr free 3 ,
84.Xr malloc 3 ,
85.Xr strdup 3
86.Sh STANDARDS
87The
88.Fn wcsdup
89function conforms to
90.St -p1003.1-2008 .
91.Sh HISTORY
92The
93.Fn wcsdup
94function was ported from
95.Nx
96and first appeared in
97.Ox 5.0 .
diff --git a/src/lib/libc/string/wcsdup.c b/src/lib/libc/string/wcsdup.c
new file mode 100644
index 0000000000..57a328a8c2
--- /dev/null
+++ b/src/lib/libc/string/wcsdup.c
@@ -0,0 +1,31 @@
1/* $OpenBSD: wcsdup.c,v 1.1 2011/07/04 04:37:34 nicm Exp $ */
2/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */
3
4/*
5 * Copyright (C) 2006 Aleksey Cheusov
6 *
7 * This material is provided "as is", with absolutely no warranty expressed
8 * or implied. Any use is at your own risk.
9 *
10 * Permission to use or copy this software for any purpose is hereby granted
11 * without fee. Permission to modify the code and to distribute modified
12 * code is also granted without any restrictions.
13 */
14
15#include <stdlib.h>
16#include <wchar.h>
17
18wchar_t *
19wcsdup(const wchar_t *str)
20{
21 wchar_t *copy;
22 size_t len;
23
24 len = wcslen(str) + 1;
25 copy = malloc(len * sizeof (wchar_t));
26
27 if (!copy)
28 return (NULL);
29
30 return (wmemcpy(copy, str, len));
31}
diff --git a/src/lib/libc/string/wcslcat.c b/src/lib/libc/string/wcslcat.c
new file mode 100644
index 0000000000..ee8ff3c343
--- /dev/null
+++ b/src/lib/libc/string/wcslcat.c
@@ -0,0 +1,56 @@
1/* $OpenBSD: wcslcat.c,v 1.4 2011/07/24 15:21:28 millert Exp $ */
2/* $NetBSD: wcslcat.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */
3
4/*
5 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <wchar.h>
22
23/*
24 * Appends src to string dst of size siz (unlike wcsncat, siz is the
25 * full size of dst, not space left). At most siz-1 characters
26 * will be copied. Always NUL terminates (unless siz <= wcslen(dst)).
27 * Returns wcslen(src) + MIN(siz, wcslen(initial dst)).
28 * If retval >= siz, truncation occurred.
29 */
30size_t
31wcslcat(wchar_t *dst, const wchar_t *src, size_t siz)
32{
33 wchar_t *d = dst;
34 const wchar_t *s = src;
35 size_t n = siz;
36 size_t dlen;
37
38 /* Find the end of dst and adjust bytes left but don't go past end */
39 while (n-- != 0 && *d != '\0')
40 d++;
41 dlen = d - dst;
42 n = siz - dlen;
43
44 if (n == 0)
45 return(dlen + wcslen(s));
46 while (*s != '\0') {
47 if (n != 1) {
48 *d++ = *s;
49 n--;
50 }
51 s++;
52 }
53 *d = '\0';
54
55 return(dlen + (s - src)); /* count does not include NUL */
56}
diff --git a/src/lib/libc/string/wcslcpy.3 b/src/lib/libc/string/wcslcpy.3
new file mode 100644
index 0000000000..7af6c74614
--- /dev/null
+++ b/src/lib/libc/string/wcslcpy.3
@@ -0,0 +1,153 @@
1.\" $OpenBSD: wcslcpy.3,v 1.6 2013/09/25 21:49:31 millert Exp $
2.\"
3.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: September 25 2013 $
18.Dt WCSLCPY 3
19.Os
20.Sh NAME
21.Nm wcslcpy ,
22.Nm wcslcat
23.Nd size-bounded wide string copying and concatenation
24.Sh SYNOPSIS
25.In wchar.h
26.Ft size_t
27.Fn wcslcpy "wchar_t *dst" "const wchar_t *src" "size_t size"
28.Ft size_t
29.Fn wcslcat "wchar_t *dst" "const wchar_t *src" "size_t size"
30.Sh DESCRIPTION
31The
32.Fn wcslcpy
33and
34.Fn wcslcat
35functions copy and concatenate wide strings respectively.
36They are designed to be safer, more consistent, and less error prone
37replacements for
38.Xr wcsncpy 3
39and
40.Xr wcsncat 3 .
41Unlike those functions,
42.Fn wcslcpy
43and
44.Fn wcslcat
45take the full size of the buffer (not just the length) and guarantee to
46terminate the result with a null wide character (as long as
47.Fa size
48is larger than 0 or, in the case of
49.Fn wcslcat ,
50as long as there is at least one wide character free in
51.Fa dst ) .
52Note that a wide character for the null wide character should be included in
53.Fa size .
54Also note that
55.Fn wcslcpy
56and
57.Fn wcslcat
58only operate on wide strings that are terminated with a null wide character
59(L'\e0').
60This means that for
61.Fn wcslcpy
62.Fa src
63must be terminated with a null wide character and for
64.Fn wcslcat
65both
66.Fa src
67and
68.Fa dst
69must be terminated with a null wide character.
70.Pp
71The
72.Fn wcslcpy
73function copies up to
74.Fa size
75\(mi 1 wide characters from the wide string
76.Fa src
77to
78.Fa dst ,
79terminating the result with a null wide character.
80.Pp
81The
82.Fn wcslcat
83function appends the wide string
84.Fa src
85to the end of
86.Fa dst .
87It will append at most
88.Fa size
89\(mi wcslen(dst) \(mi 1 wide characters, terminating the result with a null
90wide character.
91.Pp
92If the
93.Fa src
94and
95.Fa dst
96strings overlap, the behavior is undefined.
97.Sh RETURN VALUES
98The
99.Fn wcslcpy
100and
101.Fn wcslcat
102functions return the total length of the wide string they tried to create.
103For
104.Fn wcslcpy
105that means the length of
106.Fa src .
107For
108.Fn wcslcat
109that means the initial length of
110.Fa dst
111plus
112the length of
113.Fa src .
114While this may seem somewhat confusing, it was done to make
115truncation detection simple.
116.Pp
117Note, however, that if
118.Fn wcslcat
119traverses
120.Fa size
121wide characters without finding a null wide character, the length of the
122string is considered to be
123.Fa size
124and the destination wide string will not be terminated with a null wide
125character (since there was no space for it).
126This keeps
127.Fn wcslcat
128from running off the end of a wide string.
129In practice this should not happen (as it means that either
130.Fa size
131is incorrect or that
132.Fa dst
133is not terminated with a null wide character).
134The check exists to prevent potential security problems in incorrect code.
135.Sh SEE ALSO
136.Xr strlcpy 3 ,
137.Xr swprintf 3 ,
138.Xr wcsncat 3 ,
139.Xr wcsncpy 3
140.Sh HISTORY
141The
142.Fn wcslcpy
143and
144.Fn wcslcat
145functions first appeared in
146.Ox 3.8 .
147.Sh AUTHORS
148The
149.Fn wcslcpy
150and
151.Fn wcslcat
152functions are based on code by
153.An Todd C. Miller Aq Mt Todd.Miller@courtesan.com .
diff --git a/src/lib/libc/string/wcslcpy.c b/src/lib/libc/string/wcslcpy.c
new file mode 100644
index 0000000000..f49936a885
--- /dev/null
+++ b/src/lib/libc/string/wcslcpy.c
@@ -0,0 +1,52 @@
1/* $OpenBSD: wcslcpy.c,v 1.5 2011/07/24 15:21:28 millert Exp $ */
2/* $NetBSD: wcslcpy.c,v 1.2 2001/01/03 14:33:02 lukem Exp $ */
3
4/*
5 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <wchar.h>
22
23/*
24 * Copy src to string dst of size siz. At most siz-1 characters
25 * will be copied. Always NUL terminates (unless siz == 0).
26 * Returns wcslen(src); if retval >= siz, truncation occurred.
27 */
28size_t
29wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz)
30{
31 wchar_t *d = dst;
32 const wchar_t *s = src;
33 size_t n = siz;
34
35 /* Copy as many bytes as will fit */
36 if (n != 0) {
37 while (--n != 0) {
38 if ((*d++ = *s++) == '\0')
39 break;
40 }
41 }
42
43 /* Not enough room in dst, add NUL and traverse rest of src */
44 if (n == 0) {
45 if (siz != 0)
46 *d = '\0'; /* NUL-terminate dst */
47 while (*s++)
48 ;
49 }
50
51 return(s - src - 1); /* count does not include NUL */
52}
diff --git a/src/lib/libc/string/wcslen.3 b/src/lib/libc/string/wcslen.3
new file mode 100644
index 0000000000..12f81763ba
--- /dev/null
+++ b/src/lib/libc/string/wcslen.3
@@ -0,0 +1,70 @@
1.\" $OpenBSD: wcslen.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSLEN 3
36.Os
37.Sh NAME
38.Nm wcslen
39.Nd find length of a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft size_t
43.Fn wcslen "const wchar_t *s"
44.Sh DESCRIPTION
45The
46.Fn wcslen
47function computes the length of the wide string
48.Fa s .
49.Sh RETURN VALUES
50The
51.Fn wcslen
52function returns the number of wide characters that precede the terminating
53null wide character.
54.Sh SEE ALSO
55.Xr strlen 3 ,
56.Xr wcswidth 3
57.Sh STANDARDS
58The
59.Fn wcslen
60function conforms to
61.St -isoC-99
62and was first introduced in
63.St -isoC-amd1 .
64.Sh HISTORY
65The
66.Fn wcslen
67function was ported from
68.Nx
69and first appeared in
70.Ox 3.8 .
diff --git a/src/lib/libc/string/wcslen.c b/src/lib/libc/string/wcslen.c
new file mode 100644
index 0000000000..c1de4a271e
--- /dev/null
+++ b/src/lib/libc/string/wcslen.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: wcslen.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcslen.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcslen.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wcspbrk.3
new file mode 100644
index 0000000000..602bfdc3d6
--- /dev/null
+++ b/src/lib/libc/string/wcspbrk.3
@@ -0,0 +1,81 @@
1.\" $OpenBSD: wcspbrk.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSPBRK 3
36.Os
37.Sh NAME
38.Nm wcspbrk
39.Nd locate multiple wide characters in a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wcspbrk "const wchar_t *s" "const wchar_t *charset"
44.Sh DESCRIPTION
45The
46.Fn wcspbrk
47function locates in the wide string
48.Fa s
49the first occurrence of any wide character in the wide string
50.Fa charset
51and returns a pointer to this wide character.
52If no wide characters from
53.Fa charset
54occur anywhere in
55.Fa s ,
56.Fn wcspbrk
57returns
58.Dv NULL .
59.Sh SEE ALSO
60.Xr strpbrk 3 ,
61.Xr wcschr 3 ,
62.Xr wcscspn 3 ,
63.Xr wcsrchr 3 ,
64.Xr wcsspn 3 ,
65.Xr wcsstr 3 ,
66.Xr wcstok 3 ,
67.Xr wmemchr 3
68.Sh STANDARDS
69The
70.Fn wcspbrk
71function conforms to
72.St -isoC-99
73and was first introduced in
74.St -isoC-amd1 .
75.Sh HISTORY
76The
77.Fn wcspbrk
78function was ported from
79.Nx
80and first appeared in
81.Ox 3.8 .
diff --git a/src/lib/libc/string/wcspbrk.c b/src/lib/libc/string/wcspbrk.c
new file mode 100644
index 0000000000..1923abfc89
--- /dev/null
+++ b/src/lib/libc/string/wcspbrk.c
@@ -0,0 +1,53 @@
1/* $OpenBSD: wcspbrk.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcspbrk.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcspbrk.c,v 1.2 2000/12/21 05:07:25 itojun Exp
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wcsrchr.3
new file mode 100644
index 0000000000..d4a2e7cf78
--- /dev/null
+++ b/src/lib/libc/string/wcsrchr.3
@@ -0,0 +1,85 @@
1.\" $OpenBSD: wcsrchr.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSRCHR 3
36.Os
37.Sh NAME
38.Nm wcsrchr
39.Nd locate last occurrence of a wide character in a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wcsrchr "const wchar_t *s" "wchar_t c"
44.Sh DESCRIPTION
45The
46.Fn wcsrchr
47function locates the last occurrence of the wide character
48.Fa c
49in the wide string
50.Fa s .
51The terminating null wide character is considered part of the wide string.
52If
53.Fa c
54is the null wide character (L'\e0'),
55.Fn wcsrchr
56locates the terminating null wide character.
57.Sh RETURN VALUES
58The
59.Fn wcsrchr
60function returns a pointer to the located wide character or
61.Dv NULL
62if the wide character does not appear in the wide string.
63.Sh SEE ALSO
64.Xr strrchr 3 ,
65.Xr wcschr 3 ,
66.Xr wcscspn 3 ,
67.Xr wcspbrk 3 ,
68.Xr wcsspn 3 ,
69.Xr wcsstr 3 ,
70.Xr wcstok 3 ,
71.Xr wmemchr 3
72.Sh STANDARDS
73The
74.Fn wcsrchr
75function conforms to
76.St -isoC-99
77and was first introduced in
78.St -isoC-amd1 .
79.Sh HISTORY
80The
81.Fn wcsrchr
82function was ported from
83.Nx
84and first appeared in
85.Ox 3.8 .
diff --git a/src/lib/libc/string/wcsrchr.c b/src/lib/libc/string/wcsrchr.c
new file mode 100644
index 0000000000..3433310c56
--- /dev/null
+++ b/src/lib/libc/string/wcsrchr.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: wcsrchr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcsrchr.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcsrchr.c,v 1.2 2000/12/21 05:07:25 itojun Exp
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wcsspn.3
new file mode 100644
index 0000000000..3be82344dd
--- /dev/null
+++ b/src/lib/libc/string/wcsspn.3
@@ -0,0 +1,79 @@
1.\" $OpenBSD: wcsspn.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSSPN 3
36.Os
37.Sh NAME
38.Nm wcsspn
39.Nd span a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft size_t
43.Fn wcsspn "const wchar_t *s" "const wchar_t *charset"
44.Sh DESCRIPTION
45The
46.Fn wcsspn
47function spans the initial part of the wide string
48.Fa s
49as long as the wide characters from
50.Fa s
51occur in the wide string
52.Fa charset .
53.Sh RETURN VALUES
54The
55.Fn wcsspn
56function returns the number of wide characters spanned.
57.Sh SEE ALSO
58.Xr strspn 3 ,
59.Xr wcschr 3 ,
60.Xr wcscspn 3 ,
61.Xr wcspbrk 3 ,
62.Xr wcsrchr 3 ,
63.Xr wcsstr 3 ,
64.Xr wcstok 3 ,
65.Xr wmemchr 3
66.Sh STANDARDS
67The
68.Fn wcsspn
69function conforms to
70.St -isoC-99
71and was first introduced in
72.St -isoC-amd1 .
73.Sh HISTORY
74The
75.Fn wcsspn
76function was ported from
77.Nx
78and first appeared in
79.Ox 3.8 .
diff --git a/src/lib/libc/string/wcsspn.c b/src/lib/libc/string/wcsspn.c
new file mode 100644
index 0000000000..5162fa0763
--- /dev/null
+++ b/src/lib/libc/string/wcsspn.c
@@ -0,0 +1,55 @@
1/* $OpenBSD: wcsspn.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcsspn.c,v 1.3 2001/09/21 16:09:15 yamt Exp $ */
3
4/*-
5 * Copyright (c)1999,2001 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Citrus: xpg4dl/FreeBSD/lib/libc/string/wcsspn.c,v 1.3 2001/09/21 16:06:43 yamt Exp $
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wcsstr.3
new file mode 100644
index 0000000000..203a76ded3
--- /dev/null
+++ b/src/lib/libc/string/wcsstr.3
@@ -0,0 +1,88 @@
1.\" $OpenBSD: wcsstr.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WCSSTR 3
36.Os
37.Sh NAME
38.Nm wcsstr
39.Nd locate a wide substring in a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wcsstr "const wchar_t *big" "const wchar_t *little"
44.Sh DESCRIPTION
45The
46.Fn wcsstr
47function locates the first occurrence of the wide string
48.Fa little
49in the wide string
50.Fa big .
51.Pp
52If
53.Fa little
54is an empty wide string,
55.Fa big
56is returned;
57if
58.Fa little
59occurs nowhere in
60.Fa big ,
61.Dv NULL
62is returned;
63otherwise a pointer to the first wide character of the first occurrence of
64.Fa little
65is returned.
66.Sh SEE ALSO
67.Xr strstr 3 ,
68.Xr wcschr 3 ,
69.Xr wcscspn 3 ,
70.Xr wcspbrk 3 ,
71.Xr wcsrchr 3 ,
72.Xr wcsspn 3 ,
73.Xr wcstok 3 ,
74.Xr wmemchr 3
75.Sh STANDARDS
76The
77.Fn wcsstr
78function conforms to
79.St -isoC-99
80and was first introduced in
81.St -isoC-amd1 .
82.Sh HISTORY
83The
84.Fn wcsstr
85function was ported from
86.Nx
87and first appeared in
88.Ox 3.8 .
diff --git a/src/lib/libc/string/wcsstr.c b/src/lib/libc/string/wcsstr.c
new file mode 100644
index 0000000000..669e340280
--- /dev/null
+++ b/src/lib/libc/string/wcsstr.c
@@ -0,0 +1,70 @@
1/* $OpenBSD: wcsstr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wcsstr.c,v 1.3 2003/03/05 20:18:17 tshiozak Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcsstr.c,v 1.2 2000/12/21 05:07:25 itojun Exp
30 */
31
32#include <wchar.h>
33
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..33ba1318a1
--- /dev/null
+++ b/src/lib/libc/string/wcstok.3
@@ -0,0 +1,151 @@
1.\" $OpenBSD: wcstok.3,v 1.7 2011/07/25 00:38:53 schwarze Exp $
2.\"
3.\" $NetBSD: wcstok.3,v 1.3 2003/09/08 17:54:33 wiz Exp $
4.\"
5.\" Copyright (c) 1998 Softweyr LLC. All rights reserved.
6.\"
7.\" strtok_r, from Berkeley strtok
8.\" Oct 13, 1998 by Wes Peters <wes@softweyr.com>
9.\"
10.\" Copyright (c) 1988, 1991, 1993
11.\" The Regents of the University of California. All rights reserved.
12.\"
13.\" This code is derived from software contributed to Berkeley by
14.\" the American National Standards Committee X3, on Information
15.\" Processing Systems.
16.\"
17.\" Redistribution and use in source and binary forms, with or without
18.\" modification, are permitted provided that the following conditions
19.\" are met:
20.\"
21.\" 1. Redistributions of source code must retain the above copyright
22.\" notices, this list of conditions and the following disclaimer.
23.\"
24.\" 2. Redistributions in binary form must reproduce the above
25.\" copyright notices, this list of conditions and the following
26.\" disclaimer in the documentation and/or other materials provided
27.\" with the distribution.
28.\"
29.\" 3. All advertising materials mentioning features or use of this
30.\" software must display the following acknowledgement:
31.\"
32.\" This product includes software developed by Softweyr LLC, the
33.\" University of California, Berkeley, and its contributors.
34.\"
35.\" 4. Neither the name of Softweyr LLC, the University nor the names
36.\" of its contributors may be used to endorse or promote products
37.\" derived from this software without specific prior written
38.\" permission.
39.\"
40.\" THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND
41.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
42.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
43.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44.\" DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE REGENTS, OR
45.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52.\" SUCH DAMAGE.
53.\"
54.\" Original version ID:
55.\" FreeBSD: src/lib/libc/string/wcstok.3,v 1.4 2002/10/15 09:49:54 tjr Exp
56.\"
57.Dd $Mdocdate: July 25 2011 $
58.Dt WCSTOK 3
59.Os
60.Sh NAME
61.Nm wcstok
62.Nd split wide-character string into tokens
63.Sh SYNOPSIS
64.In wchar.h
65.Ft wchar_t *
66.Fn wcstok "wchar_t * restrict str" "const wchar_t * restrict sep" "wchar_t ** restrict last"
67.Sh DESCRIPTION
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.Xr strtok_r 3
94function.
95.Pp
96Since
97.Fn wcstok
98modifies the string,
99.Fa str
100should not point to an area in the initialized data segment.
101.Sh RETURN VALUES
102The
103.Fn wcstok
104function
105returns a pointer to the beginning of each subsequent token in the string,
106after replacing the token itself with a NUL wide character (L'\e0').
107When no more tokens remain, a null pointer is returned.
108.Sh EXAMPLES
109The following code fragment splits a wide-character string on
110.Tn ASCII
111space, tab, and newline characters and writes the tokens to
112standard output:
113.Bd -literal -offset indent
114const wchar_t *seps = L" \et\en";
115wchar_t *last, *tok, text[] = L" \enone\ettwo\et\etthree \en";
116
117for (tok = wcstok(text, seps, &last); tok != NULL;
118 tok = wcstok(NULL, seps, &last))
119 wprintf(L"%ls\en", tok);
120.Ed
121.Sh SEE ALSO
122.Xr strtok 3 ,
123.Xr wcschr 3 ,
124.Xr wcscspn 3 ,
125.Xr wcspbrk 3 ,
126.Xr wcsrchr 3 ,
127.Xr wcsspn 3 ,
128.Xr wcsstr 3 ,
129.Xr wmemchr 3
130.Sh STANDARDS
131The
132.Fn wcstok
133function
134conforms to
135.St -isoC-99 .
136.Sh HISTORY
137The
138.Fn wcstok
139function was ported from
140.Nx
141and first appeared in
142.Ox 3.8 .
143.Pp
144Some early implementations of
145.Fn wcstok
146omit the
147context pointer argument,
148.Fa last ,
149and maintain state across calls in a static variable like
150.Xr strtok 3
151does.
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.3 b/src/lib/libc/string/wcswidth.3
new file mode 100644
index 0000000000..a2a5b2df86
--- /dev/null
+++ b/src/lib/libc/string/wcswidth.3
@@ -0,0 +1,69 @@
1.\" $OpenBSD: wcswidth.3,v 1.2 2011/07/25 00:38:53 schwarze Exp $
2.\"
3.\" Copyright (c) 2002 Tim J. Robbins
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25.\" SUCH DAMAGE.
26.\"
27.Dd $Mdocdate: July 25 2011 $
28.Dt WCSWIDTH 3
29.Os
30.Sh NAME
31.Nm wcswidth
32.Nd number of column positions in wide-character string
33.Sh SYNOPSIS
34.In wchar.h
35.Ft int
36.Fn wcswidth "const wchar_t *pwcs" "size_t n"
37.Sh DESCRIPTION
38The
39.Fn wcswidth
40function determines the number of column positions required for the first
41.Fa n
42characters of
43.Fa pwcs ,
44or until a null wide character (L'\e0') is encountered.
45.Sh RETURN VALUES
46The
47.Fn wcswidth
48function returns 0 if
49.Fa pwcs
50is an empty string (L""),
51\-1 if a non-printing wide character is encountered,
52otherwise it returns the number of column positions occupied.
53.Sh SEE ALSO
54.Xr iswprint 3 ,
55.Xr strlen 3 ,
56.Xr wcslen 3 ,
57.Xr wcwidth 3
58.Sh STANDARDS
59The
60.Fn wcswidth
61function conforms to
62.St -p1003.1-2001 .
63.Sh HISTORY
64The
65.Fn wcswidth
66function was ported from
67.Nx
68and first appeared in
69.Ox 3.8 .
diff --git a/src/lib/libc/string/wcswidth.c b/src/lib/libc/string/wcswidth.c
new file mode 100644
index 0000000000..8ea1bdf6e6
--- /dev/null
+++ b/src/lib/libc/string/wcswidth.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: wcswidth.c,v 1.4 2011/04/04 18:16:24 stsp Exp $ */
2/* $NetBSD: wcswidth.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wcswidth.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
30 */
31
32#include <wchar.h>
33
34int
35wcswidth(const wchar_t *s, size_t n)
36{
37 int w, q;
38
39 w = 0;
40 while (n && *s) {
41 q = wcwidth(*s);
42 if (q == -1)
43 return (-1);
44 w += q;
45 s++;
46 n--;
47 }
48
49 return w;
50}
diff --git a/src/lib/libc/string/wmemchr.3 b/src/lib/libc/string/wmemchr.3
new file mode 100644
index 0000000000..17fbc9dbc5
--- /dev/null
+++ b/src/lib/libc/string/wmemchr.3
@@ -0,0 +1,81 @@
1.\" $OpenBSD: wmemchr.3,v 1.10 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WMEMCHR 3
36.Os
37.Sh NAME
38.Nm wmemchr
39.Nd locate wide character in wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wmemchr "const wchar_t *b" "wchar_t c" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn wmemchr
47function locates the first occurrence of
48.Fa c
49in wide string
50.Fa b .
51.Sh RETURN VALUES
52The
53.Fn wmemchr
54function returns a pointer to the wide character located, or
55.Dv NULL
56if no such wide character exists within
57.Fa len
58wide characters.
59.Sh SEE ALSO
60.Xr memchr 3 ,
61.Xr wcschr 3 ,
62.Xr wcscspn 3 ,
63.Xr wcspbrk 3 ,
64.Xr wcsrchr 3 ,
65.Xr wcsspn 3 ,
66.Xr wcsstr 3 ,
67.Xr wcstok 3
68.Sh STANDARDS
69The
70.Fn wmemchr
71function conforms to
72.St -isoC-99
73and was first introduced in
74.St -isoC-amd1 .
75.Sh HISTORY
76The
77.Fn wmemchr
78function was ported from
79.Nx
80and first appeared in
81.Ox 3.8 .
diff --git a/src/lib/libc/string/wmemchr.c b/src/lib/libc/string/wmemchr.c
new file mode 100644
index 0000000000..8c9517861b
--- /dev/null
+++ b/src/lib/libc/string/wmemchr.c
@@ -0,0 +1,47 @@
1/* $OpenBSD: wmemchr.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wmemchr.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wmemchr.c,v 1.2 2000/12/20 14:08:31 itojun Exp
30 */
31
32#include <wchar.h>
33
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.3 b/src/lib/libc/string/wmemcmp.3
new file mode 100644
index 0000000000..bd8ddfd120
--- /dev/null
+++ b/src/lib/libc/string/wmemcmp.3
@@ -0,0 +1,78 @@
1.\" $OpenBSD: wmemcmp.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WMEMCMP 3
36.Os
37.Sh NAME
38.Nm wmemcmp
39.Nd compare wide strings
40.Sh SYNOPSIS
41.In wchar.h
42.Ft int
43.Fn wmemcmp "const wchar_t *s1" "const wchar_t *s2" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn wmemcmp
47function compares the wide string
48.Fa s1
49against the wide string
50.Fa s2 .
51Both wide strings are assumed to be
52.Fa len
53wide characters long.
54.Sh RETURN VALUES
55The
56.Fn wmemcmp
57function returns zero if the two wide strings are identical,
58otherwise the difference between the first two differing wide characters is
59returned.
60Zero-length wide strings are always identical.
61.Sh SEE ALSO
62.Xr memcmp 3 ,
63.Xr wcscasecmp 3 ,
64.Xr wcscmp 3
65.Sh STANDARDS
66The
67.Fn wmemcmp
68function conforms to
69.St -isoC-99
70and was first introduced in
71.St -isoC-amd1 .
72.Sh HISTORY
73The
74.Fn wmemcmp
75function was ported from
76.Nx
77and first appeared in
78.Ox 3.8 .
diff --git a/src/lib/libc/string/wmemcmp.c b/src/lib/libc/string/wmemcmp.c
new file mode 100644
index 0000000000..39419aeddc
--- /dev/null
+++ b/src/lib/libc/string/wmemcmp.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: wmemcmp.c,v 1.4 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wmemcmp.c,v 1.3 2003/04/06 18:33:23 tshiozak Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wmemcmp.c,v 1.2 2000/12/20 14:08:31 itojun Exp
30 */
31
32#include <wchar.h>
33#include "locale/runetype.h"
34
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.3 b/src/lib/libc/string/wmemcpy.3
new file mode 100644
index 0000000000..2a6d528a1a
--- /dev/null
+++ b/src/lib/libc/string/wmemcpy.3
@@ -0,0 +1,79 @@
1.\" $OpenBSD: wmemcpy.3,v 1.5 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WMEMCPY 3
36.Os
37.Sh NAME
38.Nm wmemcpy
39.Nd copy wide characters
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wmemcpy "wchar_t * restrict dst" "const wchar_t * restrict src" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn wmemcpy
47function copies
48.Fa len
49wide characters from buffer
50.Fa src
51to buffer
52.Fa dst .
53If the two buffers may overlap,
54.Xr wmemmove 3
55must be used instead.
56.Sh RETURN VALUES
57The
58.Fn wmemcpy
59function returns the original value of
60.Fa dst .
61.Sh SEE ALSO
62.Xr memcpy 3 ,
63.Xr wcscpy 3 ,
64.Xr wcslcpy 3 ,
65.Xr wmemmove 3
66.Sh STANDARDS
67The
68.Fn wmemcpy
69function conforms to
70.St -isoC-99
71and was first introduced in
72.St -isoC-amd1 .
73.Sh HISTORY
74The
75.Fn wmemcpy
76function was ported from
77.Nx
78and first appeared in
79.Ox 3.8 .
diff --git a/src/lib/libc/string/wmemcpy.c b/src/lib/libc/string/wmemcpy.c
new file mode 100644
index 0000000000..9bbd83648e
--- /dev/null
+++ b/src/lib/libc/string/wmemcpy.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: wmemcpy.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wmemcpy.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp
30 */
31
32#include <string.h>
33#include <wchar.h>
34
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.3 b/src/lib/libc/string/wmemmove.3
new file mode 100644
index 0000000000..46942e7928
--- /dev/null
+++ b/src/lib/libc/string/wmemmove.3
@@ -0,0 +1,78 @@
1.\" $OpenBSD: wmemmove.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WMEMMOVE 3
36.Os
37.Sh NAME
38.Nm wmemmove
39.Nd copy wide characters
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wmemmove "wchar_t *dst" "const wchar_t *src" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn wmemmove
47function copies
48.Fa len
49wide characters from buffer
50.Fa src
51to buffer
52.Fa dst .
53The two buffers may overlap;
54the copy is always done in a non-destructive manner.
55.Sh RETURN VALUES
56The
57.Fn wmemmove
58function returns the original value of
59.Fa dst .
60.Sh SEE ALSO
61.Xr memmove 3 ,
62.Xr wcscpy 3 ,
63.Xr wcslcpy 3 ,
64.Xr wmemcpy 3
65.Sh STANDARDS
66The
67.Fn wmemmove
68function conforms to
69.St -isoC-99
70and was first introduced in
71.St -isoC-amd1 .
72.Sh HISTORY
73The
74.Fn wmemmove
75function was ported from
76.Nx
77and first appeared in
78.Ox 3.8 .
diff --git a/src/lib/libc/string/wmemmove.c b/src/lib/libc/string/wmemmove.c
new file mode 100644
index 0000000000..21bbabcd0c
--- /dev/null
+++ b/src/lib/libc/string/wmemmove.c
@@ -0,0 +1,40 @@
1/* $OpenBSD: wmemmove.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wmemmove.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wmemmove.c,v 1.2 2000/12/20 14:08:31 itojun Exp
30 */
31
32#include <string.h>
33#include <wchar.h>
34
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.3 b/src/lib/libc/string/wmemset.3
new file mode 100644
index 0000000000..2655d68bcb
--- /dev/null
+++ b/src/lib/libc/string/wmemset.3
@@ -0,0 +1,73 @@
1.\" $OpenBSD: wmemset.3,v 1.4 2013/06/05 03:39:23 tedu Exp $
2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Chris Torek and the American National Standards Committee X3,
8.\" on Information Processing Systems.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\" notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\" notice, this list of conditions and the following disclaimer in the
17.\" documentation and/or other materials provided with the distribution.
18.\" 3. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.Dd $Mdocdate: June 5 2013 $
35.Dt WMEMSET 3
36.Os
37.Sh NAME
38.Nm wmemset
39.Nd write a wide string
40.Sh SYNOPSIS
41.In wchar.h
42.Ft wchar_t *
43.Fn wmemset "wchar_t *s" "wchar_t c" "size_t len"
44.Sh DESCRIPTION
45The
46.Fn wmemset
47function writes
48.Fa len
49wide characters of value
50.Fa c
51to the wide string
52.Fa s .
53.Sh RETURN VALUES
54The
55.Fn wmemset
56function returns the original value of
57.Fa s .
58.Sh SEE ALSO
59.Xr memset 3
60.Sh STANDARDS
61The
62.Fn wmemset
63function conforms to
64.St -isoC-99
65and was first introduced in
66.St -isoC-amd1 .
67.Sh HISTORY
68The
69.Fn wmemset
70function was ported from
71.Nx
72and first appeared in
73.Ox 3.8 .
diff --git a/src/lib/libc/string/wmemset.c b/src/lib/libc/string/wmemset.c
new file mode 100644
index 0000000000..ac476dba6a
--- /dev/null
+++ b/src/lib/libc/string/wmemset.c
@@ -0,0 +1,46 @@
1/* $OpenBSD: wmemset.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
2/* $NetBSD: wmemset.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
3
4/*-
5 * Copyright (c)1999 Citrus Project,
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * citrus Id: wmemset.c,v 1.2 2000/12/20 14:08:31 itojun Exp
30 */
31
32#include <wchar.h>
33
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}